Làm cách nào chúng ta có thể đạt được tính không đồng bộ trong JavaScript?
Đây là bài #71 của loạt bài, chuyên khám phá JavaScript và các thành phần xây dựng của nó. Trong quá trình xác định và mô tả các yếu tố cốt lõi, chúng tôi cũng chia sẻ một số quy tắc chung mà chúng tôi sử dụng khi xây dựng SessionStack, một ứng dụng JavaScript cần mạnh mẽ và có hiệu suất cao để giúp các công ty tối ưu hóa trải nghiệm kỹ thuật số của người dùng của họ Show
JavaScript không đồng bộ là một trong những phần thiết yếu của ngôn ngữ vì nó chi phối cách chúng tôi xử lý các tác vụ chạy dài — chẳng hạn như tìm nạp dữ liệu từ máy chủ hoặc API Nói một cách đơn giản, chúng ta có thể xem mã không đồng bộ là mã bắt đầu một tác vụ ngay bây giờ và hoàn thành nó sau. Chúng tôi sẽ giải thích chi tiết về vấn đề này khi chúng tôi tiếp tục trong bài viết nhưng trước đó, hãy cùng tìm hiểu về mã đồng bộ — bản sao của mã không đồng bộ JavaScript, về bản chất, là một ngôn ngữ đồng bộ. Và điều này có nghĩa là JavaScript chỉ có thể thực thi một mã tại một thời điểm — từ trên xuống dưới Hãy xem xét mã dưới đây
Theo mặc định, JavaScript thực thi mã ở trên một cách đồng bộ. Và điều này có nghĩa là từng dòng một. Vì vậy, dòng 1 không thể được thực hiện trước dòng 2 và dòng 2 không thể được thực hiện trước dòng 3 Ngoài ra, JavaScript được gọi là ngôn ngữ đơn luồng. Và điều này về cơ bản có nghĩa giống như JavaScript là một ngôn ngữ đồng bộ — về bản chất Một luồng giống như một chuỗi các câu lệnh được sắp xếp như trong hình bên dưới Trong một luồng, chỉ một trong những câu lệnh đó có thể chạy tại một thời điểm nhất định. Và đây là mấu chốt của mã đồng bộ. một luồng đơn và một câu lệnh được thực thi tại một thời điểm Bạn có thể tìm hiểu thêm về chủ đề trong bài viết trước của chúng tôi trong loạt bài này Vì vậy, trong mã đồng bộ, mỗi lần chỉ có thể chạy một câu lệnh, mã đồng bộ được gọi là mã chặn Để giải thích về điều này, chúng ta hãy giả sử câu lệnh 2 trong hình trên là một tác vụ dài hạn, chẳng hạn như yêu cầu mạng tới máy chủ. Kết quả của việc này là câu lệnh 3 và 4 không thể thực hiện được cho đến khi thực hiện xong câu lệnh 2. Do đó mã đồng bộ được gọi là “mã chặn” Bây giờ, từ hiểu biết của chúng ta về mã đồng bộ, chúng ta thấy rằng nếu chúng ta có nhiều câu lệnh — các hàm trong một chuỗi thực hiện các tác vụ chạy dài, thì phần mã còn lại bên dưới các hàm này sẽ bị chặn chạy cho đến khi các hàm này hoàn thành tác vụ của chúng Mẫu này có thể ảnh hưởng tiêu cực đến hiệu suất của chương trình của chúng tôi. Và đây là lúc mã không đồng bộ xuất hiện Như đã lưu ý ở trên, mã không đồng bộ là mã bắt đầu một tác vụ ngay bây giờ và kết thúc sau. Và điều này có nghĩa là khi một chức năng không đồng bộ xử lý một tác vụ dài hạn được thực thi trong một luồng, trình duyệt sẽ di chuyển tác vụ dài hạn đó ra khỏi luồng đó và tiếp tục xử lý nó. Ngoài ra, trình duyệt đồng thời tiếp tục thực hiện các chức năng khác trong luồng đó nhưng thêm chức năng gọi lại vào luồng. Do đó, mã không đồng bộ không chặn luồng thực thi — vì vậy chúng được gọi là mã không chặn Khi tác vụ chạy dài hoàn thành, hàm gọi lại được gọi khi các hàm khác trong luồng chính thực thi xong. Và hàm gọi lại này xử lý dữ liệu được trả về từ quá trình tính toán lâu dài Do đó, mẫu lập trình không đồng bộ cho phép chương trình của chúng ta bắt đầu một tác vụ chạy dài và vẫn tiếp tục thực hiện các tác vụ khác trong luồng. Vì vậy, chúng tôi không phải đợi cho đến khi nhiệm vụ dài hạn đó kết thúc Hãy giải thích về điều này với một số ví dụ mã Hãy xem xét mã đồng bộ dưới đây Xem xét ví dụ về mã không đồng bộ bên dưới Trong đoạn mã trên, mã đồng bộ đã thực hiện tuần tự từng câu lệnh. Nhưng trong ví dụ mã không đồng bộ, việc thực thi mã không tuần tự Trong ví dụ về mã không đồng bộ, chúng tôi đã sử dụng hàm Sau phần giới thiệu này, chúng ta sẽ đi sâu vào lập trình không đồng bộ trong JavaScript Hãy bắt đầu trong phần tiếp theo Bắt đầuTrong phần giới thiệu, chúng tôi đã làm việc với một ví dụ nhỏ về mã không đồng bộ. Nhưng trong phần này, chúng ta sẽ đi sâu hơn bằng cách sử dụng các yêu cầu mạng thay cho các hàm Yêu cầu HTTPĐôi khi, chúng tôi muốn hiển thị dữ liệu như bài đăng trên blog, nhận xét, danh sách video hoặc dữ liệu người dùng được lưu trữ trên cơ sở dữ liệu hoặc máy chủ từ xa trên trang web của chúng tôi. Và để có được dữ liệu này, chúng tôi thực hiện các yêu cầu HTTP tới máy chủ hoặc cơ sở dữ liệu bên ngoài Các yêu cầu HTTP được thực hiện cho các điểm cuối API — URL được hiển thị bởi API. Và chúng tôi tương tác với các điểm cuối này để thực hiện các thao tác CRUD - đọc, tạo, cập nhật hoặc xóa dữ liệu Trong bài viết này, chúng tôi sẽ làm việc với các điểm cuối từ JSONPlaceholder. Và trong phần tiếp theo, chúng ta sẽ tìm hiểu về các mẫu lập trình không đồng bộ được sử dụng để xử lý các yêu cầu mạng trong JavaScript Các mẫu lập trình không đồng bộCác mẫu lập trình không đồng bộ trong JavaScript đã phát triển cùng với ngôn ngữ. Và trong phần này, chúng ta sẽ tìm hiểu cách các chức năng không đồng bộ đã được triển khai trong lịch sử trong JavaScript. Chúng ta sẽ tìm hiểu về các mẫu lập trình không đồng bộ như gọi lại, Lời hứa và Async-await Ngoài ra, chúng ta sẽ tìm hiểu về cách tạo yêu cầu mạng với đối tượng Thực hiện các yêu cầu HTTP với đối tượng XMLHttpRequestĐối tượng Trình xử lý sự kiện là một dạng lập trình không đồng bộ — trong đó sự kiện là tác vụ không đồng bộ hoặc tác vụ dài hạn và trình xử lý sự kiện là hàm được gọi khi sự kiện xảy ra Hãy xem xét mã dưới đây in một danh sách các bài viết như trong hình bên dưới Lưu ý, để sử dụng mã ở trên trong môi trường Nodejs, bạn sẽ cần cài đặt một gói chẳng hạn như nút-XMLHttpRequest Trong ví dụ của chúng tôi ở trên, đối tượng Lập trình không đồng bộ Với CallbacksTrong đoạn mã trên, bất cứ khi nào chúng tôi sử dụng lại chức năng Hàm gọi lại là một hàm hạng nhất được truyền dưới dạng đối số cho một hàm khác — — với kỳ vọng rằng hàm gọi lại sẽ được gọi khi một tác vụ không đồng bộ được hoàn thành Trình xử lý sự kiện là một dạng của hàm gọi lại. Và trong phần này, chúng ta sẽ tìm hiểu cách nâng cao mã của mình bằng cách sử dụng lệnh gọi lại Hãy xem xét mã dưới đây Trong đoạn mã trên, chúng tôi đã sửa đổi hàm Ngoài ra, bất cứ khi nào chúng tôi sử dụng lại chức năng địa ngục gọi lại Vì vậy, chúng tôi đã thấy rằng mẫu gọi lại giúp mã của chúng tôi có thể tái sử dụng và linh hoạt hơn. Nhưng khi chúng ta cần thực hiện một số yêu cầu mạng theo tuần tự, mẫu gọi lại có thể nhanh chóng trở nên lộn xộn và khó bảo trì Nhưng trước khi chúng tôi giải thích chi tiết về điều này, hãy cấu trúc lại chức năng Trong đoạn mã trên, chúng tôi đã tạo URL tài nguyên động bằng cách chuyển đối số Bây giờ, nếu chúng tôi thực hiện các yêu cầu mạng mà chúng tôi đã đề cập ở trên, chúng tôi sẽ kết thúc với các cuộc gọi lại được lồng sâu như bên dưới Mọi thứ thậm chí có thể trở nên tồi tệ hơn khi chúng ta lồng nhiều cuộc gọi lại vào trong các cuộc gọi lại. Và điều này được gọi là địa ngục gọi lại. Gọi lại địa ngục là nhược điểm của mẫu gọi lại Để giải quyết vấn đề gọi lại, chúng tôi sử dụng các mẫu JavaScript không đồng bộ hiện đại như lời hứa hoặc Hãy cùng tìm hiểu về Promise trong phần tiếp theo Lập trình không đồng bộ với PromiseLời hứa là nền tảng của JavaScript không đồng bộ hiện đại và lời hứa được giải quyết hoặc bị từ chối Khi một hàm không đồng bộ triển khai Promise API, hàm này sẽ trả về một đối tượng lời hứa — thường là trước khi thao tác kết thúc. Đối tượng lời hứa chứa thông tin về trạng thái hiện tại của hoạt động và các phương thức để xử lý thành công hay thất bại cuối cùng của nó Để triển khai API lời hứa, chúng tôi sử dụng hàm tạo Trong ví dụ trên, hàm tạo Hàm Bây giờ, khi chúng ta gọi hàm Hãy xem xét mã dưới đây Với kiến thức này, hãy cấu trúc lại chức năng Hãy xem xét mã dưới đây Đoạn mã trên triển khai Promises API và chúng tôi thấy rằng thay vì gọi các cuộc gọi lại trong trình xử lý sự kiện, chúng tôi đã gọi hàm Xâu chuỗi lời hứa Chúng ta đã thấy cách chúng ta xâu chuỗi các lời hứa bằng cách gọi các phương thức Chuỗi lời hứa cùng nhau cho phép chúng tôi thực hiện lần lượt các tác vụ không đồng bộ một cách rõ ràng. Để giải thích rõ hơn về điều này, chúng tôi sẽ triển khai ví dụ địa ngục gọi lại bằng API Promise Hãy xem xét mã dưới đây Lưu ý, phương thức Fetch API là một API khá hiện đại để thực hiện các yêu cầu HTTP trong JavaScript, nhưng nó có nhiều cải tiến hơn đối tượng Fetch API chỉ đơn giản là một chức năng lấy tài nguyên — một điểm cuối làm đối số của nó và trả về một lời hứa. Do đó, chúng ta có thể gọi các phương thức Chúng tôi có thể triển khai ví dụ của mình bằng cách sử dụng API Tìm nạp như bên dưới Lưu ý, trong đoạn mã trên, Ngoài ra, trong môi trường Nodejs, bạn sẽ cần cài đặt một gói chẳng hạn như tìm nạp nút để hoạt động với API Tìm nạp Lập trình không đồng bộ Với Async AwaitCác từ khóa Mặc dù Promise API có rất nhiều cải tiến so với callback, nhưng nó vẫn có thể trở nên lộn xộn khi chúng ta xâu chuỗi nhiều promise lại với nhau Nhưng với Chúng ta có thể tạo một hàm không đồng bộ bằng cách thêm từ khóa Hãy xem xét mã dưới đây Trong đoạn mã trên, chúng tôi đã cấu trúc lại hàm Ngoài ra, từ khóa Sức mạnh của từ khóa Xử lý lỗi Khi triển khai Promise API, chúng tôi xử lý lỗi bằng cách gọi phương thức Vì vậy, trong đoạn mã trên, JavaScript thực thi mã trong khối Trong bài viết này, chúng ta đã tìm hiểu về JavaScript không đồng bộ. Và các mẫu đã phát triển như thế nào trong lịch sử từ cuộc gọi lại đến Lời hứa đến Sau khi xem qua bài viết này, tôi hy vọng rằng bạn hiểu cách thức hoạt động ẩn của JavaScript không đồng bộ — ngay cả khi bạn sử dụng các API cấp cao như API tìm nạp hoặc mẫu Vì vậy, mặc dù tất cả chúng ta đều thích áp dụng các công nghệ mới, việc nâng cấp mã của chúng ta — lên các API hiện đại nên được bổ sung bằng thử nghiệm thích hợp. Và ngay cả khi chúng tôi cảm thấy mình đã thử nghiệm mọi thứ trước khi phát hành thì vẫn luôn cần phải xác minh rằng người dùng của chúng tôi có trải nghiệm tuyệt vời với sản phẩm của chúng tôi Một giải pháp như SessionStack cho phép chúng tôi phát lại hành trình của khách hàng dưới dạng video, cho thấy khách hàng thực sự trải nghiệm sản phẩm của chúng tôi như thế nào. Chúng tôi có thể nhanh chóng xác định liệu sản phẩm của mình có hoạt động theo mong đợi của họ hay không. Trong trường hợp chúng tôi thấy có điều gì đó không ổn, chúng tôi có thể khám phá tất cả các chi tiết kỹ thuật từ trình duyệt của người dùng, chẳng hạn như mạng, thông tin gỡ lỗi và mọi thứ về môi trường của họ để chúng tôi có thể dễ dàng hiểu và giải quyết vấn đề. Chúng tôi có thể đồng duyệt với người dùng, phân khúc họ dựa trên hành vi của họ, phân tích hành trình của người dùng và mở khóa các cơ hội phát triển mới cho các ứng dụng của chúng tôi JavaScript đạt được mã không đồng bộ như thế nào?Lập trình không đồng bộ giúp có thể diễn đạt thời gian chờ các hành động chạy dài mà không làm đóng băng chương trình trong các hành động này. Các môi trường JavaScript thường triển khai kiểu lập trình này bằng cách sử dụng hàm gọi lại, các hàm được gọi khi hành động hoàn tất .
Làm cách nào để tạo hàm không đồng bộ trong JavaScript?async function foo() { const p1 = new Promise((resolve) => setTimeout(() => resolve("1"), 1000));
Làm cách nào để triển khai async trong JavaScript?Hàm không đồng bộ JavaScript
. Từ khóa “async” đi kèm với hàm, cho biết rằng hàm này trả về một lời hứa . Trong chức năng này, từ khóa chờ đợi được áp dụng cho lời hứa được trả lại. Từ khóa await đảm bảo rằng chức năng chờ lời hứa giải quyết.
JavaScript có chạy không đồng bộ không?Javascript là ngôn ngữ đơn luồng đồng bộ nhưng với sự trợ giúp của vòng lặp sự kiện và lời hứa, JavaScript được sử dụng để lập trình không đồng bộ . |