1

jQuery promises に関する興味深い投稿をいくつか見つけたので、この機能を自分で試していました。以下のコードを書きましたが、問題が発生しました。

    var promises = [];
    objects.forEach(function(obj) {
        promises.push(
            $.ajax({
                url: 'myurl' + obj.id,
                dataType: 'jsonp'
            })
        )
    });

var everything = $.when.apply($,promises).done(function() {..})

ここまでは順調ですね。

その後、「すべて」を使用して、プロセス全体がいつ完了したかを簡単に理解できると考えました。

$.when(everything).done( function() { business logic })

しかし、この最後の行はすぐに起動されるため、何かが正しく機能しておらず、何が何なのかよくわかりません。手を貸していただけますか?ありがとう

4

2 に答える 2

3

問題は.done()、新しいプロミスを返さないことです。いくつかのハンドラーを受け入れて、同じプロミスを返すだけです。jQuery の promise は非常に壊れています (「jQuery の Promise 実装に関する注意」を参照してください)。他のほとんどすべての promise ライブラリでは、.done同様に動作し.thenますが、戻りundefined、エラー メッセージが沈黙していないことを確認します。jQuery では、チョコレート ファイア ガードと同じくらい便利です。

変換として機能するメソッドがあります(配列の場合と.then少し似ています)。.map

これを考慮すると、次のことができます。

var promises = objects.map(function(obj) {
    return $.ajax({
        url: 'myurl' + obj.id,
        dataType: 'jsonp'
    });
});

var everything = $.when.apply($, promises).then(function() {..});

$.when(everything).done( function() { business logic });

everythingはすでにプロミスで$.when(everything)あり、単なるパススルーであるため、実際には次のように書くことができることに注意してください。

everything.done(function () { business logic })

jQuery の Promise 実装に関する注意

jQuery の promise の実装がかなり壊れていることは注目に値します。他の Promise 実装の大部分で使用されているPromises/A+仕様には準拠していません。Promises/A+ は非常によく考えられており、多くのハードワークと実験の結果です。この仕様からの jQuery の逸脱は、多くの場合、使用を著しく困難にします。

別の実装 (例: Qまたは自分のpromise )を使用する場合は、次のようにすることができます。

Q($.ajax({
    url: 'myurl' + obj.id,
    dataType: 'jsonp'
}));

また

var Promise = require('promise');
Promise.from($.ajax({
    url: 'myurl' + obj.id,
    dataType: 'jsonp'
}));

jQuery から実際の Promises/A+ の Promise を取得します。

于 2013-07-12T16:57:49.750 に答える
1

$.when(everything)...完全に合法ですが$.when()、複数の約束パラメーターを受け入れるように設計された「約束コンバイナー」と同様に不要です。

everythingチェーンによって返されたすでにプロミスであるため、おそらく$.when.apply(...).done(...)次のように名前を付ける方が明確です。

var everything_promise = $.when.apply($, promises).then(function() {..});

さらに promise メソッドを次のように呼び出すことができます。

everything_promise.done(function() {..}).fail(function() {..});

状況によっては、代わりに を使用することもできます.then()

everything_promise.then(function() {..}, function() {..});

タイミングに関しては、元の$.when(everything)...フォームと私のeverything_promise.done(...)フォームの両方:

  • プロミスがすでに解決または拒否されている場合は、すぐに起動します
  • promise が解決または拒否されたときに、将来のある時点で起動する可能性があります
于 2013-07-12T19:50:37.047 に答える