15

配列に複数のJQueryPromisesがある状況に遭遇しました

var arrayOfPromises = [ $.Deferred(), $.Deferred(), $.Deferred(), $.Deferred() ]

そしてそれを配列のJQueryPromiseに変換する必要があります

var promiseOfArray = someTransform(arrayOfPromises)

どこ

promiseOfArray.done(function(anArray){
  alert(anArray.join(","));
});

テキストでアラートを作成します

result1、result2、result3、result4

someTransform私は現在、coffeescriptで次のように定義しています

someTransform = (arrayOfPromises) ->
  $.when(arrayOfPromises...).pipe (promises...) ->
    promises

これは次のJavaScriptに変換されます

var someTransform,
  __slice = [].slice;

someTransform = function(arrayOfPromises) {
  return $.when.apply($, arrayOfPromises).pipe(function() {
    var promises;
    promises = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
    return promises;
  });
};

これが私が探している結果のjsFiddleです。

someTransform同じ結果を達成するために定義するためのより良い(より短く、よりクリーンな)方法があるかどうか疑問に思いましたか?

4

2 に答える 2

35

配列を引数としてに適用できます$.when

var promiseOfArray = $.when.apply($, arrayOfPromises);

これの使用法をより明確にするために、私はメソッドを追加するのが好き$です:

$.whenall = function(arr) { return $.when.apply($, arr); };

今、あなたはすることができます:

$.whenall([deferred1, deferred2, ...]).done(...);

更新:デフォルトでは、doneハンドラーは各結果を個別の引数として渡します。一連の結果は得られません。

任意の数のDeferredを処理する必要があるため、特別な暗黙argumentsオブジェクトを使用して結果をループできます。

$.whenall([d1, d2, ...]).done(function() {
    for (var i = 0; i < arguments.length; i++) {
        // do something with arguments[i]
    }
});

すべてのDeferredの文字列結果を本当に結合したい場合は、小さな配列ハッカーを使用できます。 arguments配列のようなものですが、ではありませんArray

$.whenall([d1, d2, ...]).done(function() {
    alert(Array.prototype.join.call(arguments, ','));
});

done結果の配列をコールバックに返したい場合は、微調整whenall してそれを行うことができます。

$.whenall = function(arr) {
    return $.when.apply($, arr).pipe(function() {
        return Array.prototype.slice.call(arguments);
    });
};
于 2012-08-30T23:12:55.307 に答える
6

また$.when.apply、複数の promise でそれを呼び出す必要がある場合に、常に「醜い」行を入力するのが非常に面倒でした。しかしFunction.prototype.bind、救助のために!

var when = Function.prototype.apply.bind( jQuery.when, null );

今、私たちはただ呼び出すことができます

when( someArrayWithPromises ).done(function() {
});

Function.prototype.bindES5 の一部であり、ブラウザ間で非常に広く利用できます。非常に古いブラウザもサポートする必要がある場合は、簡単なshimがたくさんあります。

于 2012-08-30T23:15:52.183 に答える