等待函数 $.get done 中的代码继续
Wait to code inside function $.get done to continue
我正在用 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(我在 URL 中有一个参数)做一个 $.get,但我做不到。 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总是return最后一个
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
return 一些有用的东西,你就有了 return 一个承诺(根据你的 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
在此代码的范围内;你还没有显示它的来源。
我正在用 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(我在 URL 中有一个参数)做一个 $.get,但我做不到。 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总是return最后一个
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
return 一些有用的东西,你就有了 return 一个承诺(根据你的 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
在此代码的范围内;你还没有显示它的来源。