如何检查 Javascript Promise 是否已经实现?
How to check if Javascript Promise has been fulfilled?
我通过添加循环和 Deferred 对象对这个 example 进行了一些修改,以了解所有承诺都已实现。
我想做的是把所有的promise都push到一个数组中,当全部实现时打印出来。
这是我的代码:
get_data();
function get_data() {
var myPromise = [];
var calls = [];
var resultset = '';
for (var j = 0, k = 5; j < k; j++) {
var d = $.Deferred();
var p = get_result();
if (p.isPending()) {
console.log('pending');
}
p.then(function(resultset) {
if (p.isFulfilled()) {
myPromise.push(resultset);
calls.push(d);
}
});
}
$.when.apply($, calls).then(function() {
console.log(myPromise); // always prints an empty array.
});
}
function get_result() {
return MakeQuerablePromise(new Promise(function(result, reject) {
setTimeout(function() {
result("Yeah !");
}, 10000);
}));
}
Fiddle 完整代码
来自MDN:
The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
您的代码存在的问题是,您在 calls
数组 之后 每个延迟都已完成。这意味着当您 运行 $.when.apply($, calls)
时 calls
仍然是空的,因此由于没有未完成的延迟,它将在任何调用实际完成之前立即解析。
您的代码也不必要地令人费解。正如所建议的那样,您可以从使用 Promise 接口和 Promise.all()
中获益良多。在你的情况下,我会做这样的事情:
function get_data() {
var calls = [];
for (var j = 0, k = 5; j < k; j++) {
calls.push(get_result());
}
Promise.all(calls).then(function(results) {
console.log(results); // results is an array containing the result from each call.
});
}
无需检查承诺是否已解决,then
回调将在其解决后调用。如果 promise 相反被拒绝,则应通过在 promise 链中的某处使用 catch
回调来处理。这些是承诺的唯一可能结果。
P.S。您的代码的另一个问题是您总是将循环中创建的最后一个延迟推送到 calls
数组。这是因为 d
的范围在 for 循环之外,然后在每次迭代中重新分配,并且在异步调用解析时它已经被分配了最终的延迟。
我通过添加循环和 Deferred 对象对这个 example 进行了一些修改,以了解所有承诺都已实现。
我想做的是把所有的promise都push到一个数组中,当全部实现时打印出来。
这是我的代码:
get_data();
function get_data() {
var myPromise = [];
var calls = [];
var resultset = '';
for (var j = 0, k = 5; j < k; j++) {
var d = $.Deferred();
var p = get_result();
if (p.isPending()) {
console.log('pending');
}
p.then(function(resultset) {
if (p.isFulfilled()) {
myPromise.push(resultset);
calls.push(d);
}
});
}
$.when.apply($, calls).then(function() {
console.log(myPromise); // always prints an empty array.
});
}
function get_result() {
return MakeQuerablePromise(new Promise(function(result, reject) {
setTimeout(function() {
result("Yeah !");
}, 10000);
}));
}
Fiddle 完整代码
来自MDN:
The Promise.all(iterable) method returns a single Promise that resolves when all of the promises in the iterable argument have resolved or when the iterable argument contains no promises. It rejects with the reason of the first promise that rejects.
var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [3, 1337, "foo"]
});
您的代码存在的问题是,您在 calls
数组 之后 每个延迟都已完成。这意味着当您 运行 $.when.apply($, calls)
时 calls
仍然是空的,因此由于没有未完成的延迟,它将在任何调用实际完成之前立即解析。
您的代码也不必要地令人费解。正如所建议的那样,您可以从使用 Promise 接口和 Promise.all()
中获益良多。在你的情况下,我会做这样的事情:
function get_data() {
var calls = [];
for (var j = 0, k = 5; j < k; j++) {
calls.push(get_result());
}
Promise.all(calls).then(function(results) {
console.log(results); // results is an array containing the result from each call.
});
}
无需检查承诺是否已解决,then
回调将在其解决后调用。如果 promise 相反被拒绝,则应通过在 promise 链中的某处使用 catch
回调来处理。这些是承诺的唯一可能结果。
P.S。您的代码的另一个问题是您总是将循环中创建的最后一个延迟推送到 calls
数组。这是因为 d
的范围在 for 循环之外,然后在每次迭代中重新分配,并且在异步调用解析时它已经被分配了最终的延迟。