我用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.
第一个console.log始终显示
i is: 5 and res is: ,,,,,20
i is: 5 and res is: ,,,,,10
...
i is: 5 and res is: ,,,,,38
并且第二个console.log始终返回最后一个
Res finally is ,,,,,38
我该如何正确地做到这一点?
谢谢!
答案 0 :(得分:1)
i
的主要问题是你的回调关闭了变量 i
,而不是它在创建函数时的值。所以他们都看到i = 5
。
我不太明白为什么你重复get
五次,但是如果你愿意,你必须给回调一些东西来关闭(或者使用{{1而不是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);
};
}
};
(ES5 +,但很容易填充),但是您创建的功能超出了您的需要;在这种情况下,上述效率更高(并非可能很重要)。
然后,让Function#bind
返回一些有用的东西,让它返回一个承诺(你好像是在你的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);
};
}
};
在此代码的范围内;你还没有证明它来自哪里。