jQuery: 立即调用 when() done() 数组中的函数

jQuery: functions in array for when() done() are called immediately

我正在尝试将一些 Javascript 函数推入数组以使用 jQuery.when() 调用它们,但是在这样做时,这些函数在放入数组时已经被调用。 Here's an example 这是我的代码片段:

    var answers = someJSONFormattedData;
    var calls = [];

    function callWithIndex(i) {
        var answer = answers[i];
         api.loadUser(answer.userType, answer.userId, function(userData) {               
             answer.user = userData;
         }, null)
    };


    for(var i=0;i<answers.length;++i) {
        calls.push(callWithIndex(i));
    }


     $.when.apply($, calls).then(function() {
         var dataAsJSON = {
                 'answers': answers
         };
         //do some magic stuff with dataAsJSON           
     });

即使在执行简短的测试代码片段时,也会立即调用 test() 函数,尽管我根本不会调用它,因为我只是将它放入数组中(或至少尝试这样做)。

var test = function(i) {
    console.log("test: "+i);
}

var testArray = [];
for(var i=0;i<5;++i) {
    testArray.push(test(i));
}

您需要 push 函数的引用,而不是它的 (undefined) 结果:

试试这个:

calls.push(callWithIndex.bind(null, i));

首先感谢大家,后来发现是其他问题。问题不在于数组中的函数被立即调用,而是在 callWithIndex 函数中的 ajax 调用完成之前执行了 done() 函数。

在数组中的函数完成后调用done的正确方法是让传递的函数return其内部return值=40=]() 调用(在我的例子中是包裹在api.loadUser中)。

据我了解,jQuery 的 ajax 调用 returns 一个 Deferred 对象,并且一旦传递了所有 Deferred 对象,就会调用 done() 函数在 when() 函数中完成。恕我直言,这在 jQuery 文档中并没有得到很好的记录,他们只是使用 ajax() 调用而没有提到 return 值在这里起作用。

Here 你会找到一个关于 jQuery when(...)done(...) stuff

的好教程


最后,我的代码如下所示:

在我的 api 命名空间中,我定义了 loadUser 函数,现在 return 是 ajax return 值

api.loadUser = function(userType, userId, onSuccess, onError) {
    return $.ajax({
         //do your ajax stuff
    });
};

在我当前的 JavaScript 文件中,它现在看起来如下:

    var collectedData = [];
    var callWithIndex = function(i, userType, userId) {
        return api.loadUser(userType, userId, function(data) {
            collectedData.push(data);
        });
    }

    var deferreds = [];
    for(var i=0;i<someData.length;++i) {
        var entry = someData[i];
        deferreds.push(callWithIndex(i, entry.userType, entry.userId));
    }



    $.when.apply($, deferreds).done(function(result) {
         // do stuff with collectedData
    });

到目前为止这对我有用,现在当所有 callWithIndex 调用完成时调用 done()。

我没有使用的原因

        deferreds.push(api.loadUser(answer.userType, answer.userId, function(data) {
            //do stuff with collectedData 
        }));

是 collectedData 数组没有为 loadUser() 的成功函数定义。我想这是一些与范围相关的问题,但我不在乎。