0

I have some code that loops through an array of promises, and outputs the value.

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const promises = [
  wait(1),
  wait(3),
  wait(2),
  wait(4),
  wait(5),
];

for (var promise of promises) {
  promise.then(seconds => console.log(`waited ${seconds} seconds`));
}

The issue with this is that the promise results don't get logged in the order of the array. My expected result is this:

Waited 1 seconds
Waited 3 seconds
Waited 2 seconds
Waited 4 seconds
Waited 5 seconds

And the result was this:

Waited 1 seconds
Waited 2 seconds
Waited 3 seconds
Waited 4 seconds
Waited 5 seconds

So I would like to have something like this

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const promises = [
  wait(1),
  wait(3),
  wait(2),
  wait(4),
  wait(5),
];

for (var promise of promises) {
  // When the promise is resolved, log `Waited ${seconds} seconds`
}

How would I do this?

1
  • You should do Promise.all to get them in order Commented Jul 5, 2022 at 21:52

2 Answers 2

3

If you don't want the timers to start all at once, you shouldn't make all those wait calls at once. Instead only make the next call when the previous one's resulting promise has resolved:

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const tasks = [
  () => wait(1),
  () => wait(3),
  () => wait(2),
  () => wait(4),
  () => wait(5),
];

(async function () {
  for (const task of tasks) {
    const seconds = await task();
    console.log(`waited ${seconds} seconds more`);
  }
})();

If you do want all promises to start at the same time, and want to wait for all of them to resolve before starting to output the results, then use Promise.all:

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const promises = [
  wait(1),
  wait(3),
  wait(2),
  wait(4),
  wait(5),
];

Promise.all(promises).then(values => {
  console.log("all results are in:");
  for (const seconds of values) {
    console.log(`waited ${seconds} seconds (from the start)`);
  }
});

If you do want all promises to start at the same time, and want to wait for them to resolve only after the previous one resolved, then use await:

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const promises = [
  wait(1),
  wait(3),
  wait(2),
  wait(4),
  wait(5),
];

(async function () {
  for (const promise of promises) {
    const seconds = await promise;
    console.log(`waited ${seconds} seconds (from the start)`);
  }
})();

Sign up to request clarification or add additional context in comments.

5 Comments

@user18807217 the same pattern applies even if you make all your wait calls in the array. Just replace const seconds = await task(); with const seconds = await task;
The timers start all at once sadly, and it should be when the 3 second timer is resolved, the 2 second timer has already been resolved, therefore, the 2 seconds complete message happens right after the 3 seconds complete message
It will be if you use your original array and make the change I indicated. jsfiddle
Added some more alternatives.
@trincot best answer here
1

Daniel A. White is right - use Promise.all() - something like this:

function wait(seconds) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(seconds);
    }, seconds * 1000);
  });
}

const promises = [wait(1), wait(3), wait(2), wait(4), wait(5)];

Promise.all(promises).then((results) => {
  for (var seconds of results) {
    console.log(`waited ${seconds} seconds`);
  }
});

2 Comments

keep in mind this waits for all the promises to resolve before the .then
The issue with promise.All is that it wait's for all the promises to be resolved not logging to the console in the order of the array one by one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.