3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Promise の基礎知識

Last updated at Posted at 2019-06-16

2023/09/15 更新

Callbackは嫌だが、Promiseもなかなか馴染めない。async/awiatでいいじゃないか。しかしもう一度だけPromiseを振り返ってみたい。備忘録的なまとめです。

Promise Executor の例外 - Qiita
ES6のPromiseの基本を考えてみた - Qiita

async/awaitのわかりやすい説明です(2019/07/15追加)
async/await 入門(JavaScript)

1.Promise ライフサイクル

Promiseは非同期処理の結果を保持するプレースホルダ(オブジェクト)です。promiseは短いライフサイクルを持ちます。Pending stateでスタートし、Fulfilled state またはRejected state で終了します。

  • Pending : promiseの非同期処理はまだ終了していない
  • Fulfilled : promiseの非同期処理が終了して、成功した
  • Rejected : promiseの非同期処理が終了して、失敗した

2.Promise Executor と Fulfillment handler

Promise Executorについて
Promise Executorとは、Promiseオブジェクトを作成するときに渡すコールバック関数のことです。Promise Executorは、非同期処理の結果をPromiseオブジェクトに反映するための関数です。Promise Executorは、resolvereject という2つの引数を受け取ります2。resolveは非同期処理が成功したときに呼び出す関数で、引数に非同期処理の結果を渡します。rejectは非同期処理が失敗したときに呼び出す関数で、引数にエラー情報を渡します。Promise Executorは、Promiseオブジェクトの状態をpending(未解決)fulfilled(解決済み)rejected(拒否) のいずれかに変更することができます。
Fulfillment handler はthenメッソドの第1引数に渡される関数です。Rejection handler はthenメソッドの第2引数またはcatchメッソドの第1引数に渡される関数です。

以下はPromise Executor と Fulfillment handlerを説明するための短いコードです。

let promise = new Promise(function(resolve, reject) { // (1) Promise Executor
    console.log("Promise Executor");
    resolve(); // (3) Fulfilled stateになる
});

promise.then(function() {  // (2) Fulfillment handler
    console.log("Fulfillment handler");
});

console.log("最後の実行");

以下はPromise ExecutorとFulfillment handlerの説明です。

  • Promise Executor : Promise()コンストラクタの引数関数(非同期処理)。
  • Fulfillment handler : then()の引数関数。

以下はPromise ExecutorとFulfillment handlerの実行タイミングの説明です。

  • Promise Executor はすぐに実行されます。 (new Promise(...) call時)
  • Promise Executorの中で(3)のresolve()が呼ばれると、(2)のFulfillment handlerがjob queueの最後に追加されます。つまりhandlerは非同期処理になります。

つまりこのコードの実行結果は以下のようになります。Fulfillment handlerが一番最後に実行されます。

Promise Executor
最後の実行
Fulfillment handler

繰り返しになるので省きますが、Fulfilled handlerと全く同じことがRejected handlerについて言えます。

3.promise.then()はpromiseを返す

promise.then()はpromiseを返します。ですからpromise.then().then()...then()のようにチェインで連鎖させることができます。

let p1 = new Promise(function(resolve, reject) {
    resolve("スタート");
});

p1.then(function(value) {
    console.log(value);
}).then(function() {
    console.log("終了");
});

実行結果は以下の通りです。

スタート
終了

4.Fulfilled handler が通常の値をreturnする場合

以下はFulfilled handlerが通常の値をreturnし、次のFulfilled handlerで受け取る例です。

let p1 = new Promise(function(resolve, reject) {
    resolve(1);
});

p1.then(function(value) {
    console.log(value);         // "1"
    return value + 1;
}).then(function(value) {
    console.log(value);         // "2"
});

5.Fulfilled handler が promise をreturnする場合

以下は Fulfilled handlerがpromiseをreturnし、次のFulfilled handlerでそのpromiseのresolve値を受け取る 例です。もしp2がresolve(2)ではなくreject(2)を実行していたら、2番目のFulfillment handlerは呼ばれないことに注意してください。 この場合は、then()でなくcatch()で、Rejected handlerを定義しておけば、それが呼ばれることになります。

let p1 = new Promise(function(resolve, reject) {
    resolve(1);
});

let p2 = new Promise(function(resolve, reject) {
    resolve(2);
    // reject(2)
});

p1.then(function(value) {
    // 最初のfulfillment handler
    console.log(value);     // 1
    return p2;
}).then(function(value) {
    // 2番目のfulfillment handler
    console.log(value);     // 2
});

今回は以上です。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?