最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Promise.all not working with an array of async functions - Stack Overflow

programmeradmin3浏览0评论

Consider the following code which print messages to console after I/O operations complete, in theory.

const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  arr.map(num => {
    return (async () => {
      await foo(num);
      console.log(num);
    });
  });
}).flat();

await Promise.all(promiseArray);

I don't know why but it doesn't work. Nothing was printed to the console.


However it would work if I wrap the async function within a Promise constructor

const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  arr.map(num => {
    return new Promise(async () => {
      await foo(num);
      console.log(num);
    });
  });
}).flat();

await Promise.all(promiseArray);

How should I rewrite the code to get rid of the Promise constructor?

Consider the following code which print messages to console after I/O operations complete, in theory.

const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  arr.map(num => {
    return (async () => {
      await foo(num);
      console.log(num);
    });
  });
}).flat();

await Promise.all(promiseArray);

I don't know why but it doesn't work. Nothing was printed to the console.


However it would work if I wrap the async function within a Promise constructor

const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  arr.map(num => {
    return new Promise(async () => {
      await foo(num);
      console.log(num);
    });
  });
}).flat();

await Promise.all(promiseArray);

How should I rewrite the code to get rid of the Promise constructor?

Share Improve this question asked Jul 26, 2020 at 16:17 MaxMax 4641 gold badge5 silver badges14 bronze badges 1
  • 2 Two problems: 1. in the first callback you don't return anything, so promiseArray is just [undefined, undefined, undefined]. 2. Even if you put a return, you aren't returning promises but an array of async functions. You have to execute them to get promises. – VLAZ Commented Jul 26, 2020 at 16:24
Add a comment  | 

4 Answers 4

Reset to default 11

Promise.all takes an array of promises as its argument, not an array of async functions. Also you were missing a return statement. You should write

const promiseArray = array.flatMap(arr => {
  return arr.map(async num => {
    await foo(num);
    console.log(num);
  });
});

await Promise.all(promiseArray);

or

const promiseArray = array.map(async arr => {
  await Promise.all(arr.map(async num => {
    await foo(num);
    console.log(num);
  }));
});

await Promise.all(promiseArray);

Its normal Promise.all take an array of Promises, async function are of type function, but returns a Promise once invoked if no explicite return it will return a resolved promise with undefined value.

async function myAsyncFunction(){
  return 1; 
}

console.log(typeof myAsyncFunction)
console.log(typeof myAsyncFunction())
console.log(myAsyncFunction() instanceof Promise)

You are returning a function from map callback, not a promise. instead return foo(num). then after flattening you have an array of promises.

const foo = (num) => new Promise(resolve => setTimeout(resolve, num * 1000)); // An async I/O function in actual code
array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  return arr.map(foo); // its equal arr.map(num => foo(num));
}).flat();

const results = await Promise.all(promiseArray);
results.forEach(item => console.log(item));

An async function must return a promise. Your first implementation needs a return Statement:

const array = [[1, 2, 3], [1, 2, 3] , [1, 2, 3]];

const promiseArray = array.map(arr => {
  // returning the mapped list
  return arr.map(async (num) => {
    const result = await foo(num);
    console.log('Num: ' + num);
    // return at the end of async will generate a promise fulfillment for you.
    // see: https://developers.google.com/web/fundamentals/primers/async-functions
    return result;
  });
}).flat();

const result = await Promise.all(promiseArray);
console.log('result: ' + result);
发布评论

评论列表(0)

  1. 暂无评论