JQuery每个都没有等待内部功能完成

时间:2016-05-27 16:49:55

标签: javascript jquery ajax

我在ajax函数中有这个

$.each(data['Result'][0], function(Key, Value) {
    InputGen(Value['Type'], Value['Name'], Value['Other'], Value['Value'], function(Html){
        Table = Table + "<tr><td>"+Key+"</td><td>" + Html + "</td></tr>";
    });
});

InputGen有一个来自另一个ajax函数的回调,但是当我运行它时,循环似乎没有等待ajax完成。我将如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

  

......循环似乎没等待ajax完成。

不,因为“ajax”中的“a”代表异步;当你拨打电话时它不会发生,它会在以后发生。但是$.each循环没有理由坐下来等待它完成。

如果您不需要它(例如,ajax调用可以重叠,通常它应该是相互依赖的除外),look at Rocket Hazmat's approach

如果你需要每个ajax调用等待前一个调用完成,你就不能使用$.each(或者至少不是你的方式);相反,使用索引并通过触发下一个请求来响应回调:

// Start with first entry
var index = 0;
var array = data['Result'][0];

// Do the first request
doRequest();

function doRequest() {
    var value = array[index];
    InputGen(value['Type'], value['Name'], value['Other'], value['Value'], function(Html) {
        Table = Table + "<tr><td>"+index+"</td><td>" + Html + "</td></tr>";
        // This request is done, move to the next if any
        if (++index < array.length) {
            doRequest();
        }
    });
}

附注:在JavaScript中,绝大多数情况下,变量和非构造函数都以小写字母命名:value而不是Value等。所以我使用了indexarrayvalue以上。

旁注2:value['Type]可以更简单地写为value.Type。 (依此类推。)

答案 1 :(得分:2)

这是因为AJAX是异步。没有什么可以等待来完成它。回调将在调用完成后的某个时刻运行。到那时你的$.each(以及之后的代码)已经很久了。

这里的解决方案是使用promises。这样,一旦 all 完成AJAX调用,就可以运行回调。

您可以使用jQuery&#39; $.Deferred。如果不编辑InputGen()函数,您可以执行以下操作:

var promises = [];

$.each(data['Result'][0], function(Key, Value) {
    var d = new $.Deferred;

    InputGen(Value['Type'], Value['Name'], Value['Other'], Value['Value'], function(Html){
        d.resolve([Key, Html]);
    });

    promises.push(d.promise());
});

$.when.apply($, promises).done(function(){
    for(var i=0, length=arguments.length; i < length; i++){
        var ele = arguments[i],
            Key = ele[0],
            Html = ele[1];

        Table = Table + "<tr><td>"+Key+"</td><td>" + Html + "</td></tr>";
    }

    // In here is where you can use your updated `Table` variable.
    // You *cannot* use it outside of here, since it was not updated yet
});