admin管理员组文章数量:1421054
I'm very new to Javascript and suspect I have a basic mistake. I want to run a loop in order, but I'm using promises, and they're stuck in a "pending" state.
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 plicated than this
while (counter < 10) {
sequence = sequence.then(function() {
print(counter);
}).then(function() {
counter += 1;
});
}
My problem is very similar to this question, except that I still get stuck in the pending state even though I make the call to resolve()
. What am I doing wrong?
I'm very new to Javascript and suspect I have a basic mistake. I want to run a loop in order, but I'm using promises, and they're stuck in a "pending" state.
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 plicated than this
while (counter < 10) {
sequence = sequence.then(function() {
print(counter);
}).then(function() {
counter += 1;
});
}
My problem is very similar to this question, except that I still get stuck in the pending state even though I make the call to resolve()
. What am I doing wrong?
-
3
This pattern doesn't work because the while run synchronously and the current event loop never finishes because the while loop is running.
then()
won't fire until the next event loop. – Mark Commented Aug 19, 2018 at 22:17 - 1 Another way to think of it: if you're going to return a Promise, then you need to "resolve()" when the asynchronous even occurs, when you're USING the promise. NOT when you declare the promise (as in your example). ALSO: Iou do not NEED to use await with Promise. Two good reasons to avoid await: 1) "await()" isn't EMCA6 pliant (promises are), 2) many browsers (including IE11) don't support it. – paulsm4 Commented Aug 26, 2018 at 22:16
2 Answers
Reset to default 4You have two issues. The simpler one is that you aren't returning the result of print
, and therefore you are never waiting for the promise to resolve before continuing.
The bigger issue is that your while loop is trying to bine a synchronous loop with promises. Basically, your while loop pseudocode looks like this:
while counter < 10:
spawn an async task
end
Since counter
is only incremented in your async task, the while loop will never end. More importantly, since your while loop never stops, your async tasks never kick off, as javascript is single threaded.
You can solve this with using await
as follows:
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');
});
If you cant use async/await you can use array.reduce to sequentially resolve the promises. In that case I let the print function return a function that we can later invoke.
function print(i) {
return function() {
return new Promise(function(resolve,reject){
console.log(i);
resolve();
});
}
}
We then initialize our empty promiseArray, and our counter
const promiseArray = [];
let counter = 0;
We can now add 10 print functions to our array.
while (counter < 10) {
promiseArray.push(print(counter));
counter++;
}
Not that the print function now returns a another function. We haven't invoked that function and we haven't tried to resolve our promises. If the print function would've returned a promise (and not a function) the promise would get resolved, and it wouldn't be sequantially resolved. Since we can't guarantee that print(1) finishes before print(2). It would just start some print calls and resolve in whatever order.
To sequantially resolve the promises we use array reduce that starts with an empty promise, resolves it and then calls the next promise function.
promiseArray.reduce((init,curr) => {
return init.then(curr);
},Promise.resolve())
A full code snippet would look like this:
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 plicated than this
while (counter < 10) {
promiseArray.push(print(counter));
counter++;
}
promiseArray.reduce((init,curr) => {
return init.then(curr);
},Promise.resolve())
本文标签: Javascript promise stuck in pending stateStack Overflow
版权声明:本文标题:Javascript promise stuck in pending state - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745328405a2653698.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论