Javascript promise stuck in pending state - Stack Overflow

I'm very new to Javascript and suspect I have a basic mistake. I want to run a loop in order, but

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?

Share Improve this question asked Aug 19, 2018 at 22:07 user554481user554481 2,0754 gold badges31 silver badges53 bronze badges 2
  • 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
Add a ment  | 

2 Answers 2

Reset to default 4

You 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())

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745328406a4622764.html

相关推荐

  • Javascript promise stuck in pending state - Stack Overflow

    I'm very new to Javascript and suspect I have a basic mistake. I want to run a loop in order, but

    4小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信