我确信看起来这个问题之前已经被问了很多,但这不是典型的异步JS问题“如何在另一个完成时调用函数?”。
所以我的场景如下:我需要使用AJAX加载一组非常繁重的数据,AJAX是在他们玩的几周内安排的匹配列表。我建立了一系列承诺,当它们全部完成后,我会在DOM中完成所有匹配后再做一些其他事情。我有这样的事情:
var promises = [];
for (var i = 1; var i <= lastWeek; i++)
promises.push($.ajax({
url: "week/" + i,
success: { ... }
}));
$.when.apply($, promises).done(someFunction);
但是我注意到这会立即触发所有请求,并且可能会阻塞服务器端的进程并导致一般故障。所以我想我会以不同的方式处理这个问题,而不是立刻做出所有这些请求我在第一周制作一个,并且一旦完成那个,我做了以下,等等:
function loadWeek(week, last) {
$.get("week/" + i, function (response) {
// do whatever with the response
// make the request for the next week
if (week + 1 <= last)
loadWeek(week + 1, last);
});
}
现在我当然不能使用$.when
,因为承诺是在前一个完成时动态生成的。
我想知道JS或jQuery是否提供了一种方式来表示someFunction
函数(只有在加载了所有匹配后才应该调用的函数)。
当然,你可以说,只要在week + 1 > last
对话时调用它?好吧,我仍然需要使用promises,因为这个someFunction
不仅需要等待加载这些匹配,还需要完成另一个承诺。
所以当我说我这样做时你可以说我撒了一点谎言:
$.when.apply($, promises).done(someFunction);
实际上,promises
实际上除了匹配列表之外还有更多的函数调用,someFunction
应该有,直到所有完成。
答案 0 :(得分:1)
好的,让我们分解一下,如果我理解你正确,你想要以下
A-按顺序加载
function loadWeek(week, last) {
var deferred = $.Deferred();
(function request(week, last) {
$.get("week/" + i, function (response) {
// do whatever with the response
// make the request for the next week
if (week + 1 <= last)
request(week + 1, last);
else
deferred.resolve();
});
})(week, last);
return deferred.promise();
}
B-同时加载其他内容
function otherStuff() {
// return some promise
}
C-当A和B完成时,请致电someFunction
var promises = []
promises.push(loadWeek(1, 10));
promises.push(otherStuff(...));
$.when.apply($, promises).done(someFunction);
答案 1 :(得分:0)
有几种方法,但最简单的方法之一是对您的尝试进行小幅调整(参见***
):
function loadWeek(week, last, done) { // ***
$.get("week/" + i, function (response) {
// do whatever with the response
// make the request for the next week
if (week + 1 <= last) {
loadWeek(week + 1, last, done); // ***
} else { // ***
done(); // ***
} // ***
});
}
然后只将其他承诺推送到promises
(而不是上面loadWeek
的承诺),并且:
loadWeek(1, lastWeek, function() {
$.when.apply($, promises).then(someFunction);
});
答案 2 :(得分:0)
您需要一个在promise和函数完成时运行的函数。小解决方法:
var c=0;
function callbyboth(){
c++;
if(c==2){
//both executed
//run your code
}
}
在您的承诺上添加此内容
Promise.then(callbyboth);
在递归函数中:
if(week+1>=last){
callbyboth();
}else{
//recursion
}