我是Java的新手,并且怀疑我有一个基本错误。我想按顺序运行循环,但是我使用的是Promise,但它们处于“待定”状态。
function print(i){
return new Promise(function(resolve,reject){
console.log(i);
resolve();
});
}
counter = 0;
var sequence = Promise.resolve();
// The real while loop is much more complicated than this
while (counter < 10) {
sequence = sequence.then(function() {
print(counter);
}).then(function() {
counter += 1;
});
}
我的问题与this question非常相似,除了即使我打电话给resolve()
仍然停留在待处理状态。我在做什么错了?
答案 0 :(得分:3)
您有两个问题。比较简单的一种是,您不会返回print
的结果,因此,您永远不会等待承诺解决,然后再继续。
更大的问题是您的while循环试图将同步循环与promises结合在一起。基本上,您的while循环伪代码如下所示:
while counter < 10:
spawn an async task
end
由于counter
仅在异步任务中递增,因此while循环将永远不会结束。更重要的是,由于while循环永远不会停止,因此异步任务也不会启动,因为javascript是单线程的。
您可以使用await
来解决此问题,如下所示:
function print(i) {
return new Promise(function(resolve, reject) {
console.log(i);
resolve();
});
}
async function runLoop() {
let counter = 0;
while (counter < 10) {
const result = await print(counter);
counter += 1;
}
}
runLoop().then(() => {
console.log('done');
});
答案 1 :(得分:1)
如果您不能使用异步/等待,则可以使用array.reduce顺序解决承诺。在那种情况下,我让print函数返回一个以后可以调用的函数。
function print(i) {
return function() {
return new Promise(function(resolve,reject){
console.log(i);
resolve();
});
}
}
然后我们初始化空的promiseArray和计数器
const promiseArray = [];
let counter = 0;
我们现在可以在数组中添加10个打印功能。
while (counter < 10) {
promiseArray.push(print(counter));
counter++;
}
并不是说打印功能现在可以返回另一个功能。我们尚未调用该函数,也未尝试履行承诺。如果print函数将返回一个Promise(而不是一个函数),则Promise将得到解决,并且不会被顺序解决。由于我们不能保证print(1)在print(2)之前完成。它只会启动一些打印调用并以任何顺序解决。
要顺序解决承诺,我们使用以空promise开头的数组reduce,先解决它,再调用下一个promise函数。
promiseArray.reduce((init,curr) => {
return init.then(curr);
},Promise.resolve())
完整的代码段如下所示:
function print(i) {
return function() {
return new Promise(function(resolve,reject){
console.log(i);
resolve();
});
}
}
const promiseArray = [];
let counter = 0;
// The real while loop is much more complicated than this
while (counter < 10) {
promiseArray.push(print(counter));
counter++;
}
promiseArray.reduce((init,curr) => {
return init.then(curr);
},Promise.resolve())