最終更新:2024-07-24 (水) 18:39:26 (134d)  

JavaScript/Promise
Top / JavaScript / Promise

ECMAScript 2015で追加

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise

promise = new Promise( /* executor */ function(resolve, reject) { ... } );
promise.then(function(value) { ... }, function(reason) { ... });

内部状態

  • pending(保留)まだ非同期処理は終わっていない(成功も失敗もしていない)
    fulfilled(成功)非同期処理が正常に終了した
    rejected(拒否)非同期処理が失敗した
  • fullfilled/rejectedになるときにthenのハンドラが呼ばれる

使い方

  • const myPromise = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve("foo");
      }, 300);
    });
    myPromise
      .then(handleFulfilledA, handleRejectedA)
      .then(handleFulfilledB, handleRejectedB)
      .then(handleFulfilledC, handleRejectedC);

コンストラクタ

  • Promise のコンストラクターは一つのコールバック関数を引数として受け取る
  • コールバック関数は二つの関数、resolve と reject を引数として受け取る

コールバック関数 (executor)

  • 2つの引数resolveとrejectを取る関数。executor 関数は resolve 関数と reject 関数が渡されてPromiseが実装されるとすぐに実行されます。
  • コールバック関数内で何らかの非同期処理を行い、処理が成功すれば resolve を呼び出し、失敗すれば reject を呼びます。
    var promise = new Promise(function(resolve, reject) {
      // do a thing, possibly async, then…
    
      if (/* everything turned out fine */) {
        resolve("Stuff worked!");
      }
      else {
        reject(Error("It broke"));
      }
    });

引数

  • resolve
  • reject

エラー

  • 例外の場合はthrowするとrejectedになる

resolve

reject

then

  • "then" は2つの引数をとり、それぞれ成功時(resolved)と失敗時(rejected)のコールバック関数となります
    promise.then(function(result) {
      console.log(result); // "Stuff worked!"
    }, function(err) {
      console.log(err); // Error: "It broke"
    });

catch

finally

挙動

  • A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f.
  • A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r.
  • A promise is pending if it is neither fulfilled nor rejected.

連鎖

Promise.prototype.then?()

Promise.prototype.catch?()

  • 単なる .then() からプロミスが履行されたときのためのコールバック関数のスロットを抜いたものです

Promise.prototype.finally?()

並行処理

Promise.all()

すべてのが履行されたときに履行され、いずれかのプロミスが拒否されると拒否される。

Promise.allSettled?()

  • すべてのプロミスが決定されたときに履行される。

Promise.any?()

  • いずれかのプロミスが履行されたときに履行され、すべてのプロミスが拒否されると拒否される。

Promise.race?()

  • いずれかのプロミスが決定されたときに決定

状態

  • pending初期状態。成功も失敗もしていません。
    fulfilled処理が成功して完了したことを意味します。
    rejected処理が失敗したことを意味します。
  • settled は便宜上の用語であり、State ではありません。

Mozillaのドキュメント

仕様

メモ

  • Promise は基本的にイベントリスナーと似ていますが、以下の点で異なります。
    • Promise は一度だけ成功もしくは失敗します。2回成功/失敗したり、成功状態から失敗状態へ変化したりしません。
    • Promise がすでに成功もしくは失敗した後に成功/失敗を通知するコールバックを追加した場合、すでにイベントは完了しているにもかかわらず、正しいコールバックが呼び出されます。

標準化以前のライブラリ

関連

参考