JavaScriptで非同期処理を書く場合、コールバックでも書けることは書けますが、Promiseを用いることでより分かりやすく実装できます。 今回はこのPromiseについて、概要と使い方をまとめてみました。

Promiseとは

Promiseとは、非同期処理を抽象化したオブジェクトの生成、またそれを操作する仕組みのことをいいます。 くだけていうと、「まだ完了していないが、いずれ完了する処理」を扱うための仕組みです。

Promiseの必要性

一般的に、非同期処理には成功/失敗があり、それぞれに対する処理が必要になってきます。

この非同期処理自体はコールバックでも書けます。 ただ、書き方のルールが統一されていないので、その実装は開発者によっていろんな書き方がなされてしまいます。

Promiseは、統一的なインタフェースを提供することで、この問題を解決しています。

具体的にいうと、非同期処理を内包したPromiseオブジェクトに対して成功/失敗時の処理を書くのですが、これはthen/catchというインタフェースをとおして行なわれます。

書き方が統一されるので、非同期処理をうまくパターン化することができる、という訳です。

Promiseの使い方

それでは、Promiseの使い方について示します。 大別すると(1)Promiseオブジェクトの生成と(2)Promiseオブジェクトの利用に分けられます。

1. Promiseオブジェクトを生成する

まずは、非同期処理を書くことによってPromiseオブジェクトを生成します。

非同期処理には成功/失敗のパターンがあると思います。 この成功時にはresolve、失敗時にはrejectを呼び出します。

promise = new Promise(function (resolve, reject) {
  if (成功) {
    resolve('成功しました');
  }
  reject('失敗しました');
});

たとえば、XMLHttpRequestでデータを取得する際、成功時はresolveにレスポンスを渡し、それ以外はrejectにエラー内容を渡す、などが考えられます。

2. Promiseオブジェクトを利用する

生成したPromiseオブジェクトは、次の例のようにthen/catchをとおして利用します。 非同期処理が成功したらthen、失敗したらcatchが実行されます。

引数には、resolve/rejectで渡した引数が渡されます。

promise.then(function (message) {
  console.log(message);
}).catch(function (message) {
  console.error(message);
});

複数のPromiseを同時に扱う

Promiseには、.all/.raceという静的メソッドがあります。 使い方としては、どちらも複数のPromiseオブジェクトを登録します。

.allは、すべての処理が完了したら次のthen/catchを呼び出します。 これに対し.raceはどれかひとつが完了したら次に移ります。

以下に.allの例を示します。

Promise.all([promiseA, promiseB, ...])
  .then(...)
  .catch(...);

たとえば、複数のURLからリソースを取得し、すべて取得し終えたら次のthenに移る、などは.allが適切といえます。

参考記事