等待函数 $.get 中的代码完成以继续

Wait to code inside function $.get done to continue

本文关键字:继续 代码 函数 get 等待      更新时间:2023-09-26

我有一个用javascript做的网站,但我不能这样做。

我有这个

<script type="text/javascript">
res = new Array();
var fun1 = function () {
var control = $.Deferred();
for (i=0;i<5;i++) {
    $.get("URL", function(data){
        res[i]=data;
        console.log ("i is: " + i + "and res is: " + res);
    });
    }
}
setTimeout(function () {
control.resolve();
}, 3000);
var show = function () {
console.log("Res finally is: " + res);
}
fun1().done(show);  
</script>

我想用 5 个或更多不同的 URL 做一个 $.get (我在 URL 中有一个参数),但我做不到。 res[i] 始终是数组中的最后一个元素(在这种情况下,总是 res[5]=data,我想填充整个数组,从 0 到 15。

第一个控制台.log始终显示

i is:  5 and res is: ,,,,,20
i is:  5 and res is: ,,,,,10
...
i is:  5 and res is: ,,,,,38

和第二个控制台.log总是返回最后一个

Res finally is ,,,,,38

我怎样才能正确地做到这一点?

谢谢!

i的主要问题是您的回调关闭在变量i上,而不是创建函数时的值。所以他们都看到了i = 5.

我不太明白你为什么要重复get五次,但如果你愿意,你必须给回调一些其他的东西来关闭(或使用res.push(...)而不是res[i] = ...,但我假设你有后者的理由)。

您可以使用构建器执行此操作:

// PARTIAL solution, see below
var fun1 = function () {
    var control = $.Deferred();
    for (i=0;i<5;i++) {
        $.get("URL", buildHandler(i));
    }
    function buildHandler(index) {
        return function(data){
            res[index]=data;
            console.log ("index is: " + index + "and res is: " + res);
        };
    }
};

构建器的另一种方法是使用Function#bind(ES5+,但很容易填充),但你会创建比你需要的更多的函数;在这种情况下,上述功能更有效(并不是说它可能很重要)。

然后,要fun1返回一些有用的东西,你让它返回一个承诺(根据你的control变量,你似乎正在朝着这个方向前进),然后在所有get完成后实现承诺($.when对此很有用):

var fun1 = function () {
    var control = $.Deferred();
    var promises = [];
    for (i=0;i<5;i++) {
        promises.push($.get("URL", buildHandler(i)));
    }
    $.when.apply($, promises).then(function() {
        control.resolve(); // Or .resolveWith(), passing in something useful
    });
    return control.promise();
    function buildHandler(index) {
        return function(data){
            res[index]=data;
            console.log ("index is: " + index + "and res is: " + res);
        };
    }
};

所有这些都假定res在此代码的范围内;您尚未显示它的来源。