Hàm forEach() trong Javascript có thực thi bất đồng bộ không?

Mọi người cho e hỏi hàm forEach() này có phải hàm bất đồng bộ hay không ạ.

Tại sao trong ví dụ này của e nó không log ra theo đúng thứ tự ạ.

https://jsfiddle.net/aup2tmh9/1/

2 Likes

forEach không phải hàm bất đồng bộ.
Lý do kết quả của bạn in sai là, bạn không đợi chạy hết vòng lặp thứ nhất đã chạy vòng lặp thứ 2 và thứ 3.

forEach does not wait for promises
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Nghĩa là bạn nên dùng for of và wait trong vòng loop.

for (var endpoint of endpoints) {
    const response = await fetch(`${api}/${endpoint}`);
    const json = await response.json();
    console.log(`${endpoint} ====> `,json[0]);
}
6 Likes

Em vẫn chưa hiểu e đã dùng awiait trong async function rồi mà.
Với lại cách của anh/chị tại sao mình có thể dùng await khi mà không khai báo async-func được.
Và e muốn vẫn giữ cách dùng forEach() để nó thành đồng bộ được không ạ.

Cám ơn anh/chị ạ.

Trong Javascript, dù em có tạo ra một async function trong đó có toàn là await hay như thế nào thì khi gọi trực tiếp hàm đó, kết quả trả về vẫn là một Promise. Vì forEach không đợi kết quả trả về từ Promise nên chưa kịp chạy xong vòng lặp thứ nhất thì nó đã chạy cái thứ hai, thứ ba,… Nếu muốn biết vì sao cái này lại xảy ra thì em có thể lên MDN xem phần Polyfill (source code) của forEach là biết.

Cái này có thể là một trong hai lí do:

  1. Ví dụ minh họa nên lười ghi

  2. Sử dụng tính năng top-level await, giúp cho JS devs có thể dùng await ở top-level mà không nhất thiết phải để trong async fucntion, không phải ghi kiểu củ chuối (async _ => {})(). Tuy nhiên, tính năng này đang trong giai đoạn phát triển và hiện tại chỉ có thể dùng trong DevsTool

Đơn giản thôi, dùng thêm await là xong.

async function a(data){
    console.log(await fetch(...))
};
(async _ => {
    let arr = [...]
    arr.forEach(el => await a(el)
)()
Cách nên dùng
(async _ => {
    let arr = [...]
    arr.forEach(el => {
        console.log(await fetch(...))
    })
})()
7 Likes

E đã rõ hơn rồi, cám ơn anh nhiều lắm ạ
:star_struck: :star_struck: :star_struck:

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?