3

jQuery には、複数の s / s を操作するためのDeferredAPIの優れた機能があります。次の場合に戻ります。$.wait()DeferredPromise

  • すべてDeferreds がresolve()d されています

また

  • Deferreds の1 つreject()編集されました

ほとんどの場合、これはあなたが望むものですが、時には、それらすべてreject()がいつ編集されたかを知りたい場合があります。

すべての s が拒否され$.wait()た場合にのみ、何かを行うためのシンプルまたはエレガントな方法はありますか?Deferred

(他の使用例があるかもしれませんが、私の場合は、これを、いくつかの Deferred のうちの最初のものが解決されるのを待つことと組み合わせることです。)

4

2 に答える 2

3

Promise 仕様がオブジェクトに関して将来どのように進む可能性が高いかという精神に基づいて、PromiseInspection次の jQuery アドオン関数を使用して、すべての Promise が完了したか拒否されたかを通知します。

// pass either multiple promises as separate arguments or an array of promises
$.settle = function(p1) {
    var args;
    if (Array.isArray(p1)) {
          args = p1;
    } else {
        args = Array.prototype.slice.call(arguments);
    }

    function PromiseInspection(fulfilled, val) {
        return {
            isFulfilled: function() {
                return fulfilled;
            }, value: function() {
                return fulfilled ? val: undefined;
            }, reason: function() {
                return !fulfilled ? val: undefined;
            }
        };
    }
    return $.when.apply($, args.map(function(p) {
        // if incoming value, not a promise, then wrap it in a promise
        if (!p || (!(typeof p === "object" || typeof p === "function")) || typeof p.then !== "function") {
            p = $.Deferred().resolve(p);
        }
        // Now we know for sure that p is a promise
        // Make sure that the returned promise here is always resolved with a PromiseInspection object, never rejected
        return p.then(function(val) {
            return new PromiseInspection(true, val);
        }, function(reason) {
            // convert rejected promise into resolved promise
            // this is required in jQuery 1.x and 2.x (works in jQuery 3.x, but the extra .resolve() is not required in 3.x)
            return $.Deferred().resolve(new PromiseInspection(false, reason));
        });
    })).then(function() {
          // return an array of results which is just more convenient to work with
          // than the separate arguments that $.when() would normally return
        return Array.prototype.slice.call(arguments);
    });
}

次に、次のように使用できます。

$.settle(promiseArray).then(function(inspectionArray) {
    inspectionArray.forEach(function(pi) {
        if (pi.isFulfilled()) {
            // pi.value() is the value of the fulfilled promise
        } else {
            // pi.reason() is the reason for the rejection
        }
    });
});

$.settle()常に満たす (決して拒否しない) ことに注意してください。満たされた値はPromiseInspectionオブジェクトの配列であり、それぞれに問い合わせて、それが満たされたか拒否されたかを確認し、対応する値または理由をフェッチできます。使用例については、以下のデモを参照してください。

実際のデモ: https://jsfiddle.net/jfriend00/y0gjs31r/

于 2016-03-05T22:00:00.293 に答える