Theme
SD MILIEU

2018-11-13

[JavaScript] Promiseに関する覚書

仕様は MDN を参照

Promise を使う - JavaScript | MDN

以下のサンプルコード用の通信系の疑似関数としてget()を用意。

function get() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const value = Math.random();
            if (value > 0.2) {
                console.log('get success.')
                resolve(value);
            } else {
                console.log('get error');
                reject(value);
            }
        }, 200);
    });
}

基本形

then(onFullfilled, onRejected)onRejectedは忘れていい。catch を使おう。

get()
    .then((value) => console.log('complete with: ' + value))
    .catch((value) => console.log('failure with: ' + value));

また、then 内では必ず返り値を返すようにすること。返り値が無い場合の挙動に関して、ちゃんと書いてる文面が見つからなかったので念の為という感じ。これに関しては返り値がなかった場合の挙動の仕様を見つかれば考え直す予定。

reject の伝播

Promise チェーンの途中で reject が発生した場合、最初の catch で処理される。

例外処理が共通の場合、一番最後に catch をつけてそこでまとめて処理すれば簡潔。

get()
    .then(() => get())
    .then(() => get())
    .then(() => get())
    .then(() => get())
    .then(() => get())
    .then(() => console.log('complete'))
    .catch(() => console.log('failure'));

並列に繋ぎたい場合は Promise.all を使う

Promise.all内で reject が発生した場合は、最初に reject された値を catch に渡す。

Promise.resolve()
    .then(() => {
        const promises = [];
        promises.push(get());
        promises.push(get());

        return Promise.all(promises);
    })
    .then((values) => console.log('complete with:' + values))
    .catch((value) => console.log('failure with: ' + value));

豆知識

then 内の返り値は、Promise でない場合は内部的にPromise.resolve()でラップされる。

Promise.resolve()
    .then(() => {
        return 100;
    })
    .then((value) => {
        console.log(value);
        return Promise.resolve(100);
    })
    .then((value) => console.log(value));

then 内の throw は、Promise.reject を返すのと同様の動きをする。

Promise.resolve()
    .then(() => {
        return Promise.reject(100);
    })
    .catch((value) => console.log('reject with: ' + value));