Tại sao mã của tôi không hoạt động? Sự thật về việc sử dụng ‘async/await’ và ‘forEach’ trong JavaScript

Tram Ho


Hãy tìm hiểu tại sao mã này không hoạt động. Bạn đã bao giờ nghe thông tin sai lệch về việc sử dụng “async/await” và “forEach” trong JavaScript chưa? Một thành viên trong nhóm của chúng tôi gần đây đã nghe điều đó và tự hỏi tại sao. Bài viết này xem xét sâu hơn về chủ đề này và giải thích lý do tại sao đây là một quan niệm sai lầm phổ biến.

vấn đề

Hãy xem đoạn mã sau:

Hãy tìm hiểu tại sao mã này không hoạt động. Bạn không thể sử dụng “async/await” và “forEach” trong JavaScript?

Trong mã này, tôi có một hàm không đồng bộ “testAsync” nhận một giá trị và thêm 1 vào giá trị đó sau 100 mili giây. Sau đó, có một mảng “dữ liệu” trống và một dãy số “params”. Sử dụng phương thức “forEach” để lặp qua “params” và gọi “testAsync” trên mỗi giá trị. Và sau đó in kết quả vào nhật ký và đẩy nó vào mảng ‘dữ liệu’. Kết quả dự kiến ​​là mảng “dữ liệu” sẽ là [1, 2, 3], nhưng thực tế nó là một mảng trống.

Đây là nơi mà sự nhầm lẫn bắt đầu. Ý tưởng là đợi cho đến khi chức năng không đồng bộ hoàn tất trước khi tiếp tục bước lặp tiếp theo bằng cách sử dụng ‘await’ bên trong lệnh gọi lại ‘forEach’, nhưng không phải vậy.

sự hiểu lầm này

Vấn đề là người viết đoạn mã này hiểu sai cách hoạt động của ‘await’. ‘await’ chỉ có thể được sử dụng bên trong chức năng ‘không đồng bộ’. Ví dụ trên sử dụng ‘async’ cho chức năng gọi lại được chuyển đến ‘forEach’, khác với việc sử dụng ‘async’ cho chức năng bên ngoài. Chức năng gọi lại được chuyển đến ‘forEach’ không phải là chức năng ‘không đồng bộ’, do đó, ‘chờ đợi’ không hoạt động như dự định.

Đây là nguồn gốc của sự hiểu lầm. Nhiều người nghĩ rằng việc sử dụng ‘async’ trên hàm gọi lại được truyền cho ‘forEach’ khiến nó trở thành một hàm không đồng bộ, nhưng thực tế không phải vậy. Chức năng gọi lại vẫn là một chức năng đồng bộ, vì vậy ‘chờ đợi’ không hoạt động trong đó.

Câu trả lời là?

Tôi nên làm gì để giải quyết vấn đề này? Một giải pháp là sử dụng vòng lặp “for” thay vì “forEach”. Trong trường hợp này, ‘chờ đợi’ hoạt động chính xác.

Mã này có thể cho kết quả như mong đợi là [1, 2, 3].

Một giải pháp khác, bạn có thể sử dụng phương pháp ‘Promise.all’ với ‘map’ để đợi tất cả các lời hứa hoàn thành.

Điều này cũng cho kết quả mong đợi của [1, 2, 3].

Phần kết luận

Tóm lại, sử dụng “async/await” và “forEach” trong JavaScript là một quan niệm sai lầm phổ biến. Vấn đề là mọi người hiểu sai cách thức hoạt động của ‘await’ và nghĩ rằng việc sử dụng ‘async’ trên hàm gọi lại được truyền cho ‘forEach’ sẽ khiến hàm đó không đồng bộ. Nhưng chức năng gọi lại vẫn đồng bộ và ‘chờ đợi’ không hoạt động bên trong nó. Để giải quyết vấn đề này, bạn có thể sử dụng vòng lặp ‘for’ thông thường hoặc phương pháp ‘bản đồ’ với ‘Promise.all’. Tôi hy vọng bài viết này sẽ giải tỏa sự nhầm lẫn của bạn và giúp bạn hiểu rõ hơn về cách hoạt động của “async/await” và “forEach” trong JavaScript.

Sử dụng sai “async/await” và “forEach”! Bạn có thể sử dụng vòng lặp “for” hoặc “Promise.all” để đợi cho đến khi mọi thứ hoàn tất!

Thưởng

Ngoài ra, đây là ví dụ về cách sử dụng “async/await” và “forEach” trong JavaScript một cách trực quan hơn.

Trong ví dụ này, chúng tôi đang thêm hàm “forEachAsync” vào nguyên mẫu Array. Hàm này trả về một lời hứa sẽ giải quyết khi tất cả các cuộc gọi lại được chuyển đến nó được giải quyết, do đó, nó hoạt động giống như một hàm “forEach” thông thường. Do đó, đoạn mã cuối cùng cho kết quả như mong đợi “1 2 3 [1, 2, 3]”.

Cần lưu ý rằng việc triển khai forEachAsync này cũng có thể gặp sự cố tương tự như ví dụ mã trước đó. Đó là, nếu cuộc gọi lại được thông qua không đồng bộ hoặc bạn đang sử dụng chức năng chờ bên trong chức năng không đồng bộ.

Cách tiếp cận này không được coi là phương pháp hay vì việc thay đổi nguyên mẫu Array có thể dẫn đến kết quả không mong muốn và xung đột tên với mã khác. Bạn nên sử dụng giải pháp rõ ràng hơn như giải pháp đã đề cập trước đó.

Giới thiệu

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo