angular.js - 怎么写promise的链式调用
高洛峰
高洛峰 2017-05-15 16:51:30
0
4
509

比如我有一个A.func1()是异步的,它能返回一个对象x1,我还有一个B.func2()也是异步的,需要根据x1来执行,然后B.func2返回一个最终值值t,根据这个最终值t就进行一些提示性显示。请问这个要怎么写呢?
我自己写的代码是这样的

A.func1().
    then(function(x1) {
        B.func2(x1).
            then(function(t) {
                //do something
            })
    })

但是感觉这样用不用then就一个效果啦……还是变回金字塔了

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全員に返信(4)
世界只因有你

「連続Promise呼び出し時の状態保存」についてのコメントの補足を受けて、いくつかの戦略について詳しく説明したいと思います

最良の戦略: ステータス解除

つまり、A.func1、B.func2、および匿名関数 (func3 と呼びます) の呼び出しプロセスに状態が含まれないようにロジックを調整します。つまり、func3 が次の出力のみに依存するようにします。 func1 の出力ではなく func2; または func2 が func1 に依存しないようにするには、 Promise.all のようなものを使用して func1 と func2 の結果を同時に取得し、 func3Promise.all来同时拿到func1和func2的结果丢给func3

中策:“全局”变量维护状态

优点:state可扩展state.x2 .x3 ...
问题:很长的调用链带复杂状态的话,很容易污染出bug,代码可维护性下降严重

js
function yourLogic() { var state = {}; return A.func1() .then(function(x1) { state.x1 = x1; return B.func2(x1); }) .then(function(t) { //play with t & state.x1 return yourResult; }); }

bluebird にスローします。

中心戦略:「グローバル」変数メンテナンスステータス

利点: state を state.x2 .x3...

問題: 長い呼び出しチェーンに複雑な状態がある場合、バグが混入しやすく、コードの保守性が大幅に低下します
リーリー

bluebird のバインド メソッドは thisArg にバインドでき、状態を保持するために使用できます。原理は同じです

リーリー

中字:臨時追加配信

利点: 状態がありません。呼び出しチェーンが長い場合、この追加の状態は 2 つのステップ間で制御され、保守性が向上し、バグが発生しにくくなります

欠点: 長い呼び出しチェーンの各ステップに状態がある場合、非常に冗長になります

リーリー

もちろん、ここの内部も自分でカプセル化して最適化することができます

リーリー #🎜🎜#最後の解決策: 閉鎖メンテナンス状態#🎜🎜# #🎜🎜#実際、これは質問の本来の書き方であり、主な問題は、質問が元の「コールバック地獄」またはコールバックピラミッドの当惑にまで格下げされていることだと思います#🎜🎜# #🎜🎜#利点は...機能することです#🎜🎜# リーリー
いいねを押す +0
世界只因有你

次のように、thenPromise オブジェクトを直接返します: then 里面返回一个 Promise 的对象,如下:

javascript
A.func1() .then(function (x1) { return B.func2(x1); }) .then(function (t) { // do something });

针对你评论中说的问题,如果不使用第三方的 Promise 库的话,可以像下面这样使用:

javascriptvar promise = new Promise(function (resolve, reject) {
    var firstValue;
    A.func1()
        .then(function (x1) {
            firstValue = x1;    // 临时保存
            return B.func2(x1);
        }, reject)
        .then(function (x2) {
            resolve({
                firstValue: firstValue,
                secondValue: x2
            });
        }, reject);
});

promise.then(function (result) {
    console.log(result);    // {"firstValue": "Hello", "secondValue": "World"}
});

使用第三方的 Promise リーリー

コメントで言及された問題に対応して、サードパーティの Promise ライブラリを使用しない場合は、次のように使用できます: #🎜🎜# リーリー #🎜🎜#サードパーティの Promise ライブラリを使用すると、このプロセスを簡素化できます。 #🎜🎜#
いいねを押す +0
巴扎黑

Promise は、エレガントなチェーン呼び出しを使用できるように、Promise オブジェクトを返します。

いいねを押す +0
过去多啦不再A梦

then の関数の戻り値が直接量の場合、それは次のチェーン呼び出しで then のパラメーターとして使用されます。
戻り値に Promise のインターフェイスがある場合、Promise の解決の結果は次のようになります。
例として q を使用します

リーリー
いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート