这个问题在这里已有答案:
我正在与承诺合作。当我链接promises时,最后一个then
块不会被执行。所有其他块都被执行,但在最后一个承诺解决后没有任何反应。有人可以向我解释我错过了什么吗?
var x = 1;
$(document).ready(function() {
getJobId(token).then(function(rsp) {
return rsp;
}).then(function(job_id) {
looper().then(function(rsp) {
console.log("app finished : " + rsp); // this block never gets called
});
});
});
function getJobId(token) {
// does an API call that returns a promise
return $.ajax({
url: "url"
});
}
function looper() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
// if the call is successful
if (x == 5) {
resolve(1); // returns the value 1
} else {
x++; // we increment the value of the counter
console.log("not solved yet");
looper(); // we call the same function again
}
}, 5000); // (waits for 5 seconds)
});
}
问题是你永远不会解决你正在等待的承诺,这是looper
返回的第一个承诺。
您必须始终解决或拒绝承诺,或使其依赖于另一个承诺。在这种情况下,做到这一点的最小变化是通过将后续looper
中的promise传递给resolve
来使先前的变量依赖于后者:
resolve(looper()); // we call the same function again
但那不是我要做的。相反,我不会让looper
自称。我会直接处理它:
function looper() {
function loop(resolve, reject) {
setTimeout(function() {
// if the call is successful
if (x == 5) {
resolve(1); // returns the value 1
} else {
x++; // we increment the value of the counter
console.log("not solved yet");
loop(resolve, reject);
}
}, 5000); // (waits for 5 seconds)
}
return new Promise(loop);
}
作为一个单独的问题,你不是在处理失败。这样做很重要。在这种情况下,可能会在looper.then
处理程序中返回来自ready
的promise并添加一个catch
:
var x = 1;
$(document).ready(function() {
getJobId(token).then(function(rsp) {
return rsp;
}).then(function(job_id) {
return looper().then(function(rsp) {
console.log("app finished : " + rsp); // this block never gets called
});
}).catch(function(error) {
// Handle/report error here
});
});
function getJobId(token) {
// does an API call that returns a promise
return $.ajax({
url: "url"
});
}
function looper() {
function loop(resolve, reject) {
setTimeout(function() {
// if the call is successful
if (x == 5) {
resolve(1); // returns the value 1
} else {
x++; // we increment the value of the counter
console.log("not solved yet");
loop(resolve, reject);
}
}, 5000); // (waits for 5 seconds)
}
return new Promise(loop);
}
旁注2:既然你正在使用Promise
,我认为你的目标是现代环境。在这种情况下,您可以考虑使用fetch
(返回原生承诺)而不是$.ajax
,它返回一个jQuery jqXHR
对象,它有点与Promise兼容。