1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptのPromiseチェーンはインスタンス? .then()が受け取る値との関係の解説

Posted at

はじめに

JavaScriptでの非同期処理を扱う際、Promiseチェーンは非常に強力なパターンです。しかし、その動作原理は一見すると複雑に感じられることがあります。特に「.then()メソッドの連鎖」と「Promiseの解決値」の関係は混乱しやすいポイントです。

この記事では、以下のような疑問に答えていきます:

  • Promiseチェーンで値はどのように伝播するのか
  • ハンドラがPromiseを返す場合と通常の値を返す場合の違い
  • 「Promiseの解決」とは具体的に何を意味するのか

Promiseの基本

まず、Promiseには3つの状態があります:

  • pending(保留中): 初期状態
  • fulfilled(成功): 操作が成功し、値が利用可能になった状態
  • rejected(拒否): 操作が失敗した状態
    Promiseが「解決された」とは、そのPromiseがresolve関数を通じて値を提供した状態(fulfilled)になったことを意味します。

Promiseチェーンの動作原理

以下のコードを例に考えてみましょう:

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 1000);
}).then(function(result) {
  alert(result); // 1
  
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });
}).then(function(result) {
  alert(result); // 2
  
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });
}).then(function(result) {
  alert(result); // 4
});

このコードを理解する上で重要なポイントは以下の通りです:

1. .then()は新しいPromiseを返す
各.then()呼び出しは新しいPromiseオブジェクトを返します。つまり、チェーンの各ステップは異なるPromiseオブジェクトです。

const promise1 = new Promise(...);
const promise2 = promise1.then(...); // 新しいPromise
const promise3 = promise2.then(...); // さらに新しいPromise

2. ハンドラの戻り値が次の.then()に渡される
.then()に渡されるハンドラ関数の戻り値によって、次の.then()の動作が決まります:

ハンドラが通常の値を返す場合:その値で即座に解決されたPromiseが生成され、値がすぐに次の.then()に渡されます。
ハンドラがPromiseを返す場合:そのPromiseが解決されるまで待ち、解決値が次の.then()に渡されます。

混乱しやすいポイントの解説

最初に混乱しやすいのは、「Promiseの解決値」と「Promiseオブジェクト自体」の区別です。

.then(function(result) {
  // ここでのresultは前のPromiseの「解決値」であり、Promiseオブジェクト自体ではない
  
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve(result * 2), 1000);
  });
})

このハンドラが返すPromiseは、次の.then()にそのまま渡されるわけではありません。代わりに、このPromiseが解決されるのを待ち、その解決値が次の.then()のハンドラに渡されます。

具体例で理解する

先ほどの例の実行フローを詳しく見てみましょう:

  1. 最初のPromiseが1秒後にresolve(1)で解決される
  2. 最初の.then()ハンドラが実行され、resultに1が入る
    • alert(1)が実行される
    • 新しいPromiseを返す(このPromiseは1秒後に2で解決される)
  3. 1秒待機
  4. 返されたPromiseが2で解決されると、次の.then()ハンドラが実行される
    • resultに2が入る(前のPromiseの解決値)
    • alert(2)が実行される
    • 再び新しいPromiseを返す(このPromiseは1秒後に4で解決される)
  5. 1秒待機
  6. そのPromiseが4で解決されると、最後の.then()ハンドラが実行される
    • resultに4が入る
    • alert(4)が実行される

重要な結論

Promiseチェーンを理解する上で最も重要なのは、.then()に渡されるのは常に「解決値」であり、Promiseオブジェクト自体ではないということです。

ハンドラが通常の値を返す場合とPromiseを返す場合の違いは、単に「次の.then()が実行されるタイミング」だけです:

  • 通常の値を返す場合:即座に次の.then()が実行される
  • Promiseを返す場合:そのPromiseが解決されるまで待ってから次の.then()が実行される

結果として渡される値は同じであり、違いは「いつ次の処理が実行されるか」だけなのです。

まとめ

Promiseチェーンは、非同期処理を順序立てて実行するための強力なメカニズムです。各.then()は前のステップの結果を受け取り、次のステップに値を渡していきます。

Promiseを返すことで「この処理が終わるまで待ってから次に進む」という制御ができ、これによりコールバック地獄を避けながら読みやすく保守しやすいコードを書くことができます。

Promiseチェーンの本質を理解すれば、複雑な非同期処理も明確に構造化できるようになります。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?