我正在尝试等待ajax调用以在保存列表中的下一个模型之前完成模型的保存。我正在谷歌上搜索一些关于延迟对象的东西,对我来说是新的,另一个有递归函数的答案就是这样做的。我尝试了递归方法,因为它似乎比使用延迟对象和使用$.when.apply($, arrayOfAjaxCalls).then()
更有意义。所以代码(递归的,看起来像:
saveModel(index, numRequests) {
var self = this;
if (index < numRequests) {
var sample = self.samplesToSave[index];
return $.ajax({
url: model.url,
contentType: "application/json",
type: "POST",
data: JSON.stringify(model),
crossDomain: $.support.cors,
xhrFields: {
withCredentials: $.support.cors,
},
success: function(data) {
console.log("JUST SAVED");
console.log(data);
},
error: function(xhr: any) {
console.log(xhr);
},
}).then(() => {
self.saveModel(index + 1, numRequests);
});
}
}
我称之为:
saveModel(0, _.size(myCollection)
在调用下一个saveModel之前,它实际上并没有等待ajax调用以其当前状态结束。它基本上只是按顺序同步调用集合中每个项目的saveModel。对我缺少什么的想法?如果使用$ .Deferred有一个更好的解决方案,我也可以。感谢。
编辑:对不起,这意味着在saveModel函数的最后一行说saveModel。试图摆脱属于特定领域的部分。我正在使用打字稿,而不是coffeescript
新尝试:
saveSampleNew() {
var d = $.Deferred();
d.resolve();
var p = d.promise();
var self = this;
self.samplesToSave.forEach(sample => p = p.then(() => self.makeSaveRequest(sample)));
return p;
}
makeSaveRequest(sample) {
var self = this;
return $.ajax({
url: "samples",
contentType: "application/json",
type: "POST",
data: JSON.stringify(sample),
crossDomain: $.support.cors,
xhrFields: {
withCredentials: $.support.cors,
},
success: function(data) {
console.log("SAVED12");
console.log(data);
},
});
}
因为此代码依赖于完成的其他异步调用,所以我将这样的新尝试称为:
this.saveContainers(project).then(() => {
}).done(() => {
self.saveSampleNew();
});
答案 0 :(得分:1)
不,它应该以这种方式工作。如果您认为它不会等待,请提供有关您如何调用它以及它如何同步递归的经验的更多信息。
然而,递归调用有一个问题:
.then(function() {
self.saveModel(index + 1, numRequests);
})
then
返回的promise以及随后的saveModel
方法返回的promise确实直接解析了第一个ajax调用,它不会等待递归链。其他ajax调用仍在发生(按预期顺序执行),但未被结果承诺跟踪。
为了得到这个,并正确地链承诺,以便它与最后一个(&#34;最里面的&#34;)承诺的结果一起解析,你需要return
从回调到then
:
.then(function() {
return self.saveModel(index + 1, numRequests);
})
答案 1 :(得分:0)
我可能在这里使用for循环而不是递归调用,通常 - 我发现在这种情况下更容易阅读。
saveModel() {
var d = $.Deferred(); d.resolve();
var p = d.promise(); // to start the chain
this.samplesToSave.forEach(sample => p = p.then(() => makeSaveRequest(sample));
return p;
}
makeSaveRequest(sample) {
return $.ajax({...}); // make request using `sample` as data
}