13

実行しようとしている関数が 3 つあります。最初の 2 つは、3 番目の関数を使用するためにデータが必要な非同期処理を実行しています。1 と 2 の両方が完了したときにのみ、3 番目の関数を起動したいと考えています。これは一般的な構造ですが、最後の関数は 1 と 2 が終了する前に発火しています。

function run() {
    var data1 = {};
    var data2 = {};

    $.when(first(), second()).done(constructData());

    function first() {
        var d = new $.Deferred();

        //do a bunch of stuff async
        data1 = {};

        d.resolve();
    }
    function second() {


        var d = new $.Deferred();

        //do a bunch of stuff async
        data2 = {};
        d.resolve();
    }
    function constructData() {
        //do stuff with data1 and data2
    }

}

答えは、構造データをすぐに呼び出さないことでした

 $.when(first(), second()).done(constructData);
4

2 に答える 2

25

promise オブジェクトを返す必要があります。次の行にもエラーがあります。

$.when(first(), second()).done(constructData());

そのはず

$.when(first(), second()).done(constructData); // don't call constructData immediately

したがって、すべて一緒に次のようになります。

function run() {
    var data1 = {};
    var data2 = {};

    $.when(first(), second()).done(constructData);

    function first() {
        return $.Deferred(function() { // <-- see returning Deferred object
            var self = this;

            setTimeout(function() {   // <-- example of some async operation
                data1 = {func: 'first', data: true};
                self.resolve();       // <-- call resolve method once async is done
            }, 2000);
        });
    }
    function second() {
        return $.Deferred(function() {
            var self = this;
            setTimeout(function() {
                data2 = {func: 'second', data: true};
                self.resolve();
            }, 3000);
        });
    }
    function constructData() {
        //do stuff with data1 and data2
        console.log(data1, data2);
    }
}

http://jsfiddle.net/FwXZC/

于 2013-02-22T07:39:29.157 に答える
1

約束をして返す必要があるfirst()と思います: 。ドキュメントから:second()return d.promise();

単一の引数が jQuery.when に渡され、それが Deferred または Promise でない場合、解決された Deferred として扱われ、添付された doneCallbacks がすぐに実行されます。

whenこれが、電話の呼び出しがconstructData早すぎる理由であると思われます。

コードから判断するのは難しいですがd.resolve()、非同期操作が完了した後に呼び出していることを確認してください。

を明示的に設定するより自然な方法はdata1、が呼び出さdata2れたときに提供されるデータを使用することです。resolveこれは、when呼び出しが次のようになることを意味します。

$.when(first(), second()).done(function(result1, result2) {
    data1 = result1[0];
    data2 = result2[0];

    constructData();
});

メソッドに提供される結果の正確な形式はdone、遅延オブジェクトの性質に依存することに注意してください。promise が への呼び出しから返された場合$.ajax、結果は の形式になり[data, statusText, jqXhrObject]ます。

于 2013-02-22T07:30:49.023 に答える