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

javascript - Is Array.forEach asynchronous? - Stack Overflow

programmeradmin3浏览0评论

According to JavaScript, Node.js: is Array.forEach asynchronous?, Array.forEach is synchronous. However, for my code below:

function wait5() {
    return new Promise(resolve => 
    setTimeout(resolve, 5000));
}

async function main() {
   console.log("Start");
   [1,2].forEach(async (e) => {
      const d = await wait5().then(()=> console.log("5s later") )
   })
   console.log("This should e last!");
}

main();

The output is:

Start
This should e last!
5s later
5s later

with the two "5s later" ing out in rapid succession.

Why is this the case?

If I use a normal for loop:

async function main() {
   console.log("Start");
   for (let i=0;i<2;i++) {
      const d = await wait5().then(()=> console.log("5s later") )
   }
   console.log("This should e last!");
}

then the result is what I wanted:

Start
5s later
5s later
This should e last!

According to JavaScript, Node.js: is Array.forEach asynchronous?, Array.forEach is synchronous. However, for my code below:

function wait5() {
    return new Promise(resolve => 
    setTimeout(resolve, 5000));
}

async function main() {
   console.log("Start");
   [1,2].forEach(async (e) => {
      const d = await wait5().then(()=> console.log("5s later") )
   })
   console.log("This should e last!");
}

main();

The output is:

Start
This should e last!
5s later
5s later

with the two "5s later" ing out in rapid succession.

Why is this the case?

If I use a normal for loop:

async function main() {
   console.log("Start");
   for (let i=0;i<2;i++) {
      const d = await wait5().then(()=> console.log("5s later") )
   }
   console.log("This should e last!");
}

then the result is what I wanted:

Start
5s later
5s later
This should e last!
Share Improve this question edited Aug 30, 2018 at 17:12 u936293 asked Aug 30, 2018 at 16:59 u936293u936293 16.3k34 gold badges121 silver badges219 bronze badges 6
  • 8 The .forEach() mechanism on its own performs no asynchronous work. The same cannot be said for code that's passed in as the callback, which is free to do anything it wants. – Pointy Commented Aug 30, 2018 at 17:01
  • 1 await is the key here. – zero298 Commented Aug 30, 2018 at 17:02
  • 1 This has nothing to do with forEach and everything to do with [1,2].forEach(async (e) => where you declared the callback to forEach to be async. – gforce301 Commented Aug 30, 2018 at 17:02
  • And note that nothing pays attention to the Promise returned from each call to the .forEach() callback. – Pointy Commented Aug 30, 2018 at 17:02
  • This is your second question about asynchronicity in JavaScript. I'm all for that, please keep asking well formed questions. However, is there a core question that might be better asked like "What does asynchronicity actually mean in JS?" or "How does the event loop work?"? I'm not sure how better to help you. – zero298 Commented Aug 30, 2018 at 17:05
 |  Show 1 more ment

2 Answers 2

Reset to default 10

forEach is synchronous. Your particular callback function, however, is not. So forEach synchronously calls your function, which starts its work, once for each entry in the array. Later, the work that started finishes asynchronously, long after forEach has returned.

The issue is that your callback is async, not that forEach is asynchronous.

In general, when you're using an API like forEach that doesn't do anything with the return value (or doesn't expect a promise as a return value), either:

  1. Don't pass it an async function, or

  2. Ensure that you handle errors within the function itself

Otherwise, you'll get unhandled errors if something goes wrong in the function.

Or of course:

  1. Use a try/catch block within the async function to catch and handle/report errors within the function itself.

It looks like you're declaring an async function inside of a caller that really doesn't care for that sort of thing, forEach. Declaring a function async makes it promise-like, but that promise is only useful if acted on.

If you need a promise-aware forEach, that's something you could implement, though Promise.each in libraries like Bluebird already do that.

发布评论

评论列表(0)

  1. 暂无评论