1. ホーム
  2. ジャバスクリプト

[解決済み] .then()チェーンで以前のプロミス結果にアクセスするにはどうすればよいですか?

2022-04-17 03:08:41

質問

私は、コードを 約束 を構築し、素晴らしい長さの フラットプロミスチェーン で構成され、複数の .then() のコールバックがあります。最終的には、何らかの複合値を返したいので、複数の 中間プロミス結果 . しかし、シーケンスの途中の解決値は、最後のコールバックのスコープにありません、どのように私はそれらにアクセスするのですか?

function getExample() {
    return promiseA(…).then(function(resultA) {
        // Some processing
        return promiseB(…);
    }).then(function(resultB) {
        // More processing
        return // How do I gain access to resultA here?
    });
}

解決方法は?

ECMAScriptのハーモニー

もちろん、この問題は言語設計者にも認識されていました。彼らは多くの作業を行い 非同期関数の提案 にやっと入った。

ECMAScript 8

は1つも必要ありません。 then 非同期関数(呼び出されたときにプロミスを返す)では、プロミスが直接解決するのを待つだけなので、呼び出しやコールバック関数はもう必要ありません。また、条件、ループ、try-catch-clauseなどの任意の制御構造も備えていますが、ここでは便宜上不要とします。

async function getExample() {
    var resultA = await promiseA(…);
    // some processing
    var resultB = await promiseB(…);
    // more processing
    return // something using both resultA and resultB
}

ECMAScript 6

ES8を待っている間、私たちはすでに非常によく似た構文を使っていました。ES6では ジェネレータ関数 これは、実行を任意の位置の yield というキーワードがあります。これらのスライスは互いに独立して、非同期にも実行できます。これはちょうど、次のステップを実行する前にプロミスの解決を待ちたいときに行うことです。

専用のライブラリ(例えば co または task.js ) だけでなく、多くのプロミス・ライブラリは、ヘルパー関数 ( Q , ブルーバード , いつ を行う、...) この非同期ステップバイステップ実行 プロミスを生成するジェネレータ関数を渡すと、あなたのために。

var getExample = Promise.coroutine(function* () {
//               ^^^^^^^^^^^^^^^^^ Bluebird syntax
    var resultA = yield promiseA(…);
    // some processing
    var resultB = yield promiseB(…);
    // more processing
    return // something using both resultA and resultB
});

これはNode.jsではバージョン4.0から動作しており、いくつかのブラウザ(またはその開発版)は比較的早くからジェネレータ構文をサポートしていました。

ECMAScript 5

しかし、後方互換性を確保したいのであれば、トランスパイラを使用しないと、それらを使用することはできません。ジェネレータ関数と非同期関数の両方は、現在のツールでサポートされています。 ジェネレータ 非同期関数 .

そして、その他にも多くの コンパイル可能なJS言語 は、非同期プログラミングを容易にすることに特化しています。これらは通常、以下のような構文を使用します。 await を使用します(例. アイスコーヒースクリプト ) がありますが、その他にもHaskellのような do -のような記法があります(例. ラテJs , 単項目 , ピュアスクリプト または LispyScript ).