我是Javascript的新手,我怀疑我有一个基本的错误。我想按顺序运行循环,但我使用的是promises,它们被困在“挂起”状态。
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(),我仍然停留在挂起状态。我做错了什么?
发布于 2018-08-20 06:19:15
你有两个问题。更简单的一种方法是,您不会返回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');
});
发布于 2018-08-20 06:28:36
如果您不能使用async/await,您可以使用array.reduce按顺序解析promises。在这种情况下,我让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函数现在返回另一个函数。我们还没有调用该函数,也没有尝试解析我们的承诺。如果print函数返回promise (而不是函数),promise就会被解析,而且不会按顺序解析。因为我们不能保证print(1)在print(2)之前完成。它只会启动一些打印调用,并以任何顺序进行解析。
为了按顺序解析promise,我们使用数组reduce,它从一个空promise开始,解析它,然后调用下一个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())
https://stackoverflow.com/questions/51922202
复制相似问题