JavaScript
promise

JavaScript における Promise に関する備忘録

More than 1 year has passed since last update.

IE11 に対応するため、既存のロジックを async/await を使わないで書き換えようとしたのがきっかけ。

Promise の動作おさらい

非同期で進んでいる処理が完了/失敗した場合の処理を記述するのに用いる。

ここでは基本動作の理解のため、非同期ではない処理で例を記述する。

成功した場合の例
new Promise(function (resolve, reject) {
        // 本来ここに非同期で進める処理を書く
        resolve('ほげ');
    })
    .then(function (x) {
        console.log('OK:' + x);
    })
    .catch(function (x) {
        console.log('NG:' + x);
    });

// 'OK: ほげ'
失敗した場合の例
new Promise(function (resolve, reject) {
        // 本来ここに非同期で進める処理を書く
        reject('ふが');
    })
    .then(function (x) {
        console.log('OK:' + x);
    })
    .catch(function (x) {
        console.log('NG:' + x);
    });

// 'NG: ふが'

つまり resolve, reject(というより、コンストラクタに渡した関数の第一、第二引数)の呼び出しと、then, catch に渡した関数の実行がそれぞれ対応している。

async/await の挙動

関数定義の前に async と付けると、その関数は async function になる。

async function 内では await が利用できる。

await は文の前に書くと、その文の処理が終わるまで次の文の実行を行わないようになる(=同期処理にできる)。

async/awaitを使った例
async function requestHoge() {
    var requestUrl = // (略)...

    var result;
    await axios.get(requestUrl, requestOptions)
        .then(function (response) {
            result = response.data;
        })
        .catch(function (error) {
            throw error;
        });

    return result;
}

async function main () {
    var hoge;

    try {
        hoge = await requestHoge();
    } catch (error) {
        console.error(error);
        return;
    }

    // 変数 hoge を使った処理
    // ...
}

axios: Promise ベースの http クライアント。本来 get() は非同期。

async/await を使わないで書き換え

上記のコードを async/await を使わずに書き換えると次のようになる。

Promise を返すようにするのがポイント。

async/awaitを使わずに書き換えた例
function requestHoge() {
    var requestUrl = // (略)...

    return new Promise(function (resolve, reject) {
        axios.get(requestUrl, requestOptions)
            .then(function (response) {
                resolve(response.data);
            })
            .catch(function (error) {
                reject(error);
            });
    });
}

function main () {
    requestHoge()
        .then(function (result) {
            var hoge = reusult;

            // 変数 hoge を使った処理
            // ...
        })
        .catch(function (error) {
            console.error(error);
        });
}

※ IE11 対応する場合 Promise の Polyfill も必要