- vừa được xem lúc

Blog#112: 🌸Why your code isn't working: The truth behind using "async/await" with "forEach" in JavaScript🌸

0 0 27

Người đăng: NGUYỄN ANH TUẤN

Theo Viblo Asia

The main goal of this article is to help you improve your English level. I will use Simple English to introduce to you the concepts related to software development. In terms of IT knowledge, it might have been explained better and more clearly on the internet, but remember that the main target of this article is still to LEARN ENGLISH.


Hi, I'm Tuan, a Full-stack Web Developer from Tokyo 😊. Follow my blog to not miss out on useful and interesting articles in the future.

Introduction

Have you ever been told that you can't use "async/await" with "forEach" in JavaScript? One of our team members was recently told this and it got us wondering - why is this the case? In this article, we'll take a closer look at this topic and explain why this is a common misconception.

The Problem

Let's take a look at the following code:

async function testAsync(v) { await new Promise((resolve) => { setTimeout(resolve, 100); }); return v + 1;
} const data = [];
const params = [0, 1, 2];
params.forEach(async (v) => { const res = await testAsync(v); console.log(res); data.push(res);
});
console.log(data);
[]
1
2
3

In this code, we have an asynchronous function "testAsync" that takes in a value and returns that value plus 1 after a 100ms delay. We then have an empty array "data" and an array of numbers "params". We use the "forEach" method to loop through "params" and call "testAsync" for each value. We then log the result and push it into the "data" array. The expectation is that the "data" array will end up being [1, 2, 3], but in reality, it is an empty array.

This is where the confusion starts. The idea is that by using "await" inside of the "forEach" callback, we are waiting for the asynchronous function to complete before moving on to the next iteration. But this is not the case.

The Misconception

The problem here is that the person writing this code is misunderstanding how "await" works. "Await" only works when it is used inside of an "async" function. In the example above, we are using "async" on the callback function passed to "forEach", but this is not the same as using "async" on the outer function. The callback function passed to "forEach" is not an "async" function and therefore, "await" does not work as intended.

This is where the misconception comes in. Many people think that by using "async" on the callback function passed to "forEach", they are making that function asynchronous. But this is not the case. The callback function is still a synchronous function and therefore, "await" does not work inside of it.

The Solution

So, what can we do to fix this problem? One solution is to use a regular "for" loop instead of "forEach". In this case, "await" will work as intended.

for (const v of params) { const res = await testAsync(v); console.log(res); data.push(res);
}
console.log(data);

This code will give us the expected result of [1, 2, 3].

Another solution is to use the "map" method and then "Promise.all" to wait for all the promises to complete.

const data = await Promise.all(params.map(async (v) => { const res = await testAsync(v); return res;
}));
console.log(data);

This will give us the same expected result of [1, 2, 3].

Conclusion

In conclusion, using "async/await" with "forEach" in JavaScript is a common misconception. The problem is that people are misunderstanding how "await" works and think that by using "async" on the callback function passed to "forEach", they are making that function asynchronous. However, the callback function is still synchronous and "await" does not work inside of it. To fix this problem, we can use a regular "for" loop or the "map" method with "Promise.all" to wait for all the promises to complete. I hope this article has helped clear up any confusion and you now have a better understanding of how "async/await" and "forEach" work in JavaScript.

Bonus

As a bonus, here is an example of a more intuitive way to use "async/await" with "forEach" in JavaScript.

Array.prototype.forEachAsync = async function(callback, thisArg) { const promises = []; this.forEach(function(...args) { promises.push(callback.call(this, ...args)); }, thisArg); return await Promise.all(promises);
}
async function sampleAsync(v) { await new Promise((resolve) => { setTimeout(resolve, 1000); }); return v + 1;
} const data = [];
const params = [0, 1, 2];
await params.forEachAsync(async (v) => { const res = await sampleAsync(v); console.log(res); data.push(res);
});
console.log(data);

In this example, we are adding an "forEachAsync" function to the Array prototype. This function works just like the regular "forEach" function but it returns a promise that resolves when all the callbacks passed to it have resolved. This means that we can use "await" to wait for all the callbacks to complete before moving on. As a result, in the last code snippet, we will get the output "1 2 3 [1, 2, 3]" which is the expected result.

It's worth noting that this implementation of forEachAsync could also have an issue similar to the previous code examples if the callback passed to it is not asynchronous, or if it uses await inside of a non-async function.

This approach is also not considered a good practice, as modifying the Array prototype could lead to unexpected results and naming collisions with other code. It's better to use a more explicit solution, like the ones previously mentioned.

And Finally

As always, I hope you enjoyed this article and learned something new. Thank you and see you in the next articles!

If you liked this article, please give me a like and subscribe to support me. Thank you. 😊


The main goal of this article is to help you improve your English level. I will use Simple English to introduce to you the concepts related to software development. In terms of IT knowledge, it might have been explained better and more clearly on the internet, but remember that the main target of this article is still to LEARN ENGLISH.

Ref

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 525

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 433

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 153

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 145

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 110

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 245