admin管理员组

文章数量:1287514

I'm using some Promises to fetch some data and I got stuck with this problem on a project.

example1 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo1');
  }, 3000);
});

example2 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo2');
  }, 3000);
});

doStuff = () =>  {
  const listExample = ['a','b','c'];
  let s = "";
  listExample.forEach((item,index) => {
    console.log(item);
    example1().then(() => {
        console.log("First");
        s = item;
    });
    example2().then(() => {
        console.log("Second");
    });
  });
  console.log("The End");
};

If I call the doStuff function on my code the result is not correct, the result I expected is shown below.

RESULT                EXPECTED
a                     a
b                     First
c                     Second
The End               b
First                 First
Second                Second
First                 c
Second                First
First                 Second
Second                The End

At the end of the function no matter how I try, the variable s gets returned as "", I expected s to be "c".

I'm using some Promises to fetch some data and I got stuck with this problem on a project.

example1 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo1');
  }, 3000);
});

example2 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo2');
  }, 3000);
});

doStuff = () =>  {
  const listExample = ['a','b','c'];
  let s = "";
  listExample.forEach((item,index) => {
    console.log(item);
    example1().then(() => {
        console.log("First");
        s = item;
    });
    example2().then(() => {
        console.log("Second");
    });
  });
  console.log("The End");
};

If I call the doStuff function on my code the result is not correct, the result I expected is shown below.

RESULT                EXPECTED
a                     a
b                     First
c                     Second
The End               b
First                 First
Second                Second
First                 c
Second                First
First                 Second
Second                The End

At the end of the function no matter how I try, the variable s gets returned as "", I expected s to be "c".

Share Improve this question edited Mar 15, 2022 at 9:55 VLAZ 29.1k9 gold badges62 silver badges84 bronze badges asked Dec 22, 2018 at 3:39 andremonteiroandremonteiro 431 silver badge4 bronze badges 2
  • is this code in the browser or on a node server? – skellertor Commented Dec 22, 2018 at 3:56
  • Possible duplicate of How do I return the response from an asynchronous call? – ic3b3rg Commented Dec 22, 2018 at 4:18
Add a ment  | 

2 Answers 2

Reset to default 6

It sounds like you want to wait for each Promise to resolve before initializing the next: you can do this by awaiting each of the Promises inside an async function (and you'll have to use a standard for loop to asynchronously iterate with await):

const example1 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo1');
  }, 500);
});

const example2 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo2');
  }, 500);
});

const doStuff = async () =>  {
  const listExample = ['a','b','c'];
  for (let i = 0; i < listExample.length; i++) {
    console.log(listExample[i]);
    await example1();
    const s = listExample[i];
    console.log("Fisrt");
    await example2();
    console.log("Second");
  }
  console.log("The End");
};

doStuff();

await is only syntax sugar for Promises - it's possible (just a lot harder to read at a glance) to re-write this without async/await:

const example1 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo1');
  }, 500);
});

const example2 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo2');
  }, 500);
});

const doStuff = () =>  {
  const listExample = ['a','b','c'];
  return listExample.reduce((lastPromise, item) => (
    lastPromise
      .then(() => console.log(item))
      .then(example1)
      .then(() => console.log("Fisrt"))
      .then(example2)
      .then(() => console.log('Second'))
  ), Promise.resolve())
    .then(() => console.log("The End"));
};

doStuff();

If you want NOT to wait for each promise to finish before starting the next;

You can use Promise.all() to run something after all your promises have resolved;

example1 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo1');
  }, 3000);
});

example2 = () => new Promise(function(resolve, reject) {
  setTimeout(function() {
    resolve('foo2');
  }, 3000);
});

doStuff = () => {
  const listExample = ['a','b','c'];
  let s = "";
  let promises = []; // hold all the promises
  listExample.forEach((item,index) => {
    s = item; //moved
    promises.push(example1() //add each promise to the array
    .then(() => {  
        console.log(item); //moved
        console.log("First");
    }));
    promises.push(example2() //add each promise to the array
    .then(() => {
        console.log("Second");
    }));
  });
  Promise.all(promises) //wait for all the promises to finish (returns a promise)
  .then(() => console.log("The End")); 
  return s;
};
doStuff();

本文标签: javascriptHow to wait a Promise inside a forEach loopStack Overflow