6

完了する必要がある非同期タスクが多数あるため、promise を使用しています。

各プロミスがいつ実行されたか (解決と拒否の両方) を検出する必要があります。それまで処刑を続けてはいけません。

私はこのようなものを使用していました:

$.when(promise1, promise2, ...).always();

しかし、このコードは間違っています。なぜなら、whenメソッドには遅延評価があり、promise の 1 つが失敗するとすぐに返されるからです。したがって、alwaysプロミスの 1 つが失敗するとすぐに、コールバックも実行されます。

私は回避策をコーディングすることを考えていましたが、このユースケースは非常に一般的であるため、誰かがすでにそれを行っているか、jQuery だけを使用してこれを行う方法さえあるかもしれません (そうでない場合Promise.whenNonLazyPromise.when(promise1, promise2, ..., false)、将来。

これは可能ですか?

4

3 に答える 3

1

スミシー、

まず、約束が配列にあると仮定しましょう。

var promises = [....];

あなたが望むように見えるものは.when()、これらのプロミスの何らかの変換に適用され、拒否されたプロミスは解決済みに変換されますが、すでに解決されているプロミスには透過的です。

必要な操作は、次のように非常に簡潔に記述できます。

$.when.apply(null, $.map(promises, resolvize)).done(...);
//or, if further filtering by .then() is required ...
$.when.apply(null, $.map(promises, resolvize)).then(...);

resolvize変換メカニズムはどこにありますか。

では、 はresolvize()どのように見えますか? .then()の特徴を利用して、解決された約束と拒否された約束を区別し、それに応じて対応しましょう。

function resolvize(promise) {
    //Note: null allows a resolved promise to pass straight through unmolested;
    return promise.then(null, function() {
        return $.Deferred().resolve.apply(null, arguments).promise();
    });
}

テストされていない

いくつresolvizeかの外側のスコープで$.when.apply($.map(promises, resolvize))は、必要な場所で式で使用できるようにすることができます。新しいメソッドで jQuery を拡張する程度にまでは行かなくても、これで十分である可能性が高くなります。

変換がどのように達成されるかに関係なく、潜在的な問題が発生します。つまり、コールバックの各引数について.done()、対応する promise が最初に解決されたか拒否されたかを知ることができます。それは、拒否を解決に変えるために支払う代償です。ただし、元の約束が解決/拒否されたパラメーターから元のステータスを検出できる場合があります。

于 2013-10-04T14:20:02.557 に答える