我刚刚开始使用 Promise 进行多个 Ajax 调用,但我不知道需要创建多少个。我找到了这些帖子:
jQuery Deferred - waiting for multiple AJAX requests to finish jQuery make dynamic ajax calls and wait for them to complete
所以我尝试使用 Promise,在这个简单的例子中:
function doSomething1() {
var deferred1 = $.Deferred();
setTimeout(function() {
deferred1.resolve();
}, 2000);
return deferred1.promise();
}
function doSomething2() {
var deferred2 = $.Deferred();
setTimeout(function () {
deferred2.resolve();
}, 1000);
return deferred2.promise();
}
var promise = doSomething1();
var promise2 = doSomething2();
function multiplePromises() {
var promises = [];
for (var i = 0; i < 3; i++) {
var deferred = $.Deferred();
deferred.resolve();
promises.push(deferred);
}
return $.when.apply(undefined, promises).promise();
}
multiplePromises().done(function () {
console.log("yay");
});
我立刻就得到了“耶”。现在为了模拟 ajax 调用,我尝试使用 setTimeout
。像这样:
function multiplePromises2() {
var promises = [];
for (var i = 0; i < 3; i++) {
setTimeout(function () {
var deferred = $.Deferred();
deferred.resolve();
promises.push(deferred);
},2000);
}
return $.when.apply(undefined, promises).promise();
}
multiplePromises2().done(function () {console.log("timeout and promises");});
我没有得到实际的两秒延迟。如果我尝试这个:
function multiplePromises2() {
var promises = [];
for (var i = 0; i < 3; i++) {
var deferred = $.Deferred();
setTimeout(function () {
deferred.resolve();
},2000);
promises.push(deferred);
}
return $.when.apply(undefined, promises).promise();
}
我根本没有收到 multiplePromises2 已完成的消息。所以在我实际的ajax调用中,我无法使用deferred。我尝试这样做:
saveNewProjects(projects) {
var projectPromises: any[] = [];
for (var projectName in projects) {
var project = projects[projectName][0].Project;
if (project && project.id == 0 && project.name !== null) {
var deferred = $.Deferred();
var postProject = $.ajax({
url: "projects",
contentType: "application/json",
type: "POST",
data: JSON.stringify(project),
crossDomain: $.support.cors,
xhrFields: {
withCredentials: $.support.cors,
},
success: function (data) {
deferred.resolve(data);
},
});
projectPromises.push(postProject);
}
}
return $.when.apply($, projectPromises).promise();
}
我这样称呼该函数:
this.saveNewProjects(projects).then(() => {
我是否考虑了 promise 并适当推迟?它似乎没有到达我的 then 或 done 回调。提前致谢。
最佳答案
这是一个令人讨厌的小问题,但问题并不是因为您错误地使用了 deferreds - 因为您的想法是正确的:而是因为您遇到了闭包问题。
让我们举个例子:
function multiplePromises2() {
var promises = [];
for (var i = 0; i < 3; i++) {
var deferred = $.Deferred();
setTimeout(function () {
deferred.resolve();
},2000);
promises.push(deferred);
}
return $.when.apply(undefined, promises).promise();
}
这看起来很无辜。但不幸的是,您实际上并没有为循环的每次迭代定义一个新变量deferred
。 JavaScript 解释器将所有变量声明移动到作用域的顶部。所以这实际上等同于:
function multiplePromises2() {
var promises, deferred;
promises = [];
for (var i = 0; i < 3; i++) {
deferred = $.Deferred();
setTimeout(function () {
deferred.resolve();
},2000);
promises.push(deferred);
}
return $.when.apply(undefined, promises).promise();
}
您能明白为什么现在可能出现问题吗? setTimeout 中对变量 deferred 的引用实际上发生了变化,因为您在每次迭代时都会更新 deferred 。因此,当 2 秒结束时,您将解决单个延迟(在 Promise[2] 处)三次。为了证明这一点,您可以在 setTimeout 中添加以下行: console.log(promises.indexOf(deferred));
。
现在我们已经确定了问题,解决起来就很容易了。只是一个标准的 IIFE 解决方案:
function multiplePromises2() {
var promises, deferred;
promises = [];
for (var i = 0; i < 3; i++) {
deferred = $.Deferred();
(function(deferred) {
setTimeout(function () {
deferred.resolve();
},2000);
promises.push(deferred);
})(deferred);
}
return $.when.apply(undefined, promises).promise();
}
关于javascript - 何时解决 ajax 调用中的 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23576209/