FreeStyleWiki

Promiseとかasync/await

[Javascript]

Promiseとかasync/await

  • Javascriptの非同期処理を同期処理に書き換える方法について

async/awaitのだいたいの挙動

  • Promiseを返す関数はawaitというキーワードを使えば待ち合わせできる
    • Javascriptのライブラリにはコールバックを持つものが多くあるが、これはだいたいの場合非同期処理になる
    • そしてだいたいの場合非同期にしたいとは思っていないので、同期処理にしたいという思惑があるはず
    • コールバック関数をもつ関数をPromiseで包むと、awaitを使うことで同期処理に変換できる
  • awaitを使う関数にはasyncをつけなければならない
  • 調子に乗ってawaitをつけまくるとasync functionだらけになる(それはいいのか?)
async function() {
    // 何か非同期の関数
    var result = await someAsyncFunction();
    return result;
}

Promiseの返り値

  • Promiseを返す際はresolve, rejectで返す
    • これによりコールバックのネストを減らし、非同期処理を同期処理に変換できる
    • ただし、rejectを返した場合返り値はundefinedになってしまう
    • 返り値を確認したい場合は、thencatch側で行うべきだろう(この場合でもawaitを書いておけば同期処理になる)
// Promiseを返却する側
function routePromise(request) {
    return new Promise(function(resolve, reject) {
        var d = new google.maps.DirectionsService();
        d.route(request, function(result, status){
            if (status == google.maps.DirectionsStatus.OK) {
                resolve([result, status]);
            } else {
                reject([result, status]);
            }
        });
    });
}

var result, status;
await routePromise(request)
        .then((res) => {
            [result, status] = res; // resolveされたときの返り値
        })
        .catch((err) => {
            [result, status] = err; // rejectされたときの返り値
        });

async/awaitというキーワードの実装状況

  • 最新のchromeではもちろん動作するが、一部実装されていないブラウザなどもあるのでそこは注意が必要だ
    • もしプログラムの提供先が古い端末である場合コールバック地獄で頑張るしかないかもしれない
    • 参考:Promiseを使う - JavaScript - MDN
      • 「昔は、複数の非同期処理を順番に実行するには、従来のコールバックの悲運のピラミッドを作ることになりました。」