13

我正在尝试运行三个功能,前两个正在做一些需要数据供第三个使用的异步内容。我希望第三个函数仅在 1 和 2 都完成时触发。这是一般结构,但最终功能是在 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

您应该返回承诺对象。您在此行中也有错误:

$.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()在异步操作完成后调用。

您可能会发现一种更自然的显式设置方法data1data2使用resolve调用时提供的数据。这意味着您的when电话看起来像这样:

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

    constructData();
});

请注意,提供给该done方法的结果的确切格式取决于延迟对象的性质。如果从调用返回承诺$.ajax,则结果应为[data, statusText, jqXhrObject].

于 2013-02-22T07:30:49.023 回答