Javascript theo mặc định là không đồng bộ?

Trong các máy tính tiêu dùng hiện tại, mọi chương trình chạy trong một khoảng thời gian cụ thể và sau đó nó dừng thực thi để chương trình khác tiếp tục thực hiện. Thứ này chạy theo chu kỳ nhanh đến mức không thể nhận ra. Chúng tôi nghĩ rằng máy tính của chúng tôi chạy nhiều chương trình cùng một lúc, nhưng đây là một ảo ảnh [ngoại trừ trên các máy đa bộ xử lý]

Các chương trình nội bộ sử dụng các ngắt, một tín hiệu được phát ra cho bộ xử lý để thu hút sự chú ý của hệ thống

Bây giờ chúng ta đừng đi sâu vào nội dung của vấn đề này, nhưng hãy nhớ rằng việc các chương trình không đồng bộ và tạm dừng thực thi cho đến khi chúng cần chú ý là điều bình thường, cho phép máy tính thực thi những thứ khác trong thời gian chờ đợi. Khi một chương trình đang đợi phản hồi từ mạng, nó không thể tạm dừng bộ xử lý cho đến khi yêu cầu kết thúc

Thông thường, các ngôn ngữ lập trình là đồng bộ và một số cung cấp cách quản lý tính không đồng bộ trong ngôn ngữ hoặc thông qua các thư viện. C, Java, C#, PHP, Go, Ruby, Swift và Python đều được đồng bộ hóa theo mặc định. Một số trong số chúng xử lý các hoạt động không đồng bộ bằng cách sử dụng các luồng, tạo ra một quy trình mới

JavaScript

JavaScript được đồng bộ theo mặc định và là luồng đơn. Điều này có nghĩa là mã không thể tạo luồng mới và chạy song song

Các dòng mã được thực thi nối tiếp nhau, chẳng hạn

JScopy

Nhưng JavaScript được sinh ra bên trong trình duyệt, ban đầu công việc chính của nó là phản hồi các hành động của người dùng, như ________ 48, ________ 49, ________ 50, ________ 00, v.v. Làm sao nó có thể làm được điều này với mô hình lập trình đồng bộ?

Câu trả lời là trong môi trường của nó. Trình duyệt cung cấp một cách để thực hiện điều đó bằng cách cung cấp một bộ API có thể xử lý loại chức năng này

Gần đây hơn, Nút. js đã giới thiệu môi trường non-blocking I/O để mở rộng khái niệm này sang quyền truy cập tệp, cuộc gọi mạng, v.v.

gọi lại

Bạn không thể biết khi nào người dùng sẽ nhấp vào nút. Vì vậy, bạn xác định một trình xử lý sự kiện cho sự kiện nhấp chuột. Trình xử lý sự kiện này chấp nhận một chức năng, chức năng này sẽ được gọi khi sự kiện được kích hoạt

JScopy

Đây là cái gọi là gọi lại

Gọi lại là một chức năng đơn giản được truyền dưới dạng giá trị cho một chức năng khác và sẽ chỉ được thực thi khi sự kiện xảy ra. Chúng ta có thể làm điều này vì JavaScript có các hàm hạng nhất, có thể được gán cho các biến và chuyển qua các hàm khác [được gọi là các hàm bậc cao hơn]

Thông thường, bạn sẽ bọc tất cả mã máy khách của mình trong trình xử lý sự kiện

JScopy

1 trên đối tượng

JScopy

2, đối tượng này chỉ chạy chức năng gọi lại khi trang đã sẵn sàng

JScopy

Gọi lại được sử dụng ở mọi nơi, không chỉ trong các sự kiện DOM

Một ví dụ phổ biến là bằng cách sử dụng bộ hẹn giờ

JScopy

Yêu cầu XHR cũng chấp nhận gọi lại, trong ví dụ này bằng cách gán chức năng cho thuộc tính sẽ được gọi khi một sự kiện cụ thể xảy ra [trong trường hợp này, trạng thái của yêu cầu thay đổi]

JScopy

Xử lý lỗi trong cuộc gọi lại

Làm thế nào để bạn xử lý lỗi với các cuộc gọi lại? . js được thông qua. tham số đầu tiên trong bất kỳ hàm gọi lại nào là đối tượng lỗi. gọi lại lỗi đầu tiên

Nếu không có lỗi, đối tượng là

JScopy

3. Nếu có lỗi, nó chứa một số mô tả về lỗi và thông tin khác

JScopy

Vấn đề với các cuộc gọi lại

Gọi lại là tuyệt vời cho các trường hợp đơn giản

Tuy nhiên, mỗi cuộc gọi lại sẽ thêm một mức độ lồng nhau và khi bạn có nhiều cuộc gọi lại, mã bắt đầu phức tạp rất nhanh

JScopy

Đây chỉ là một mã 4 cấp độ đơn giản, nhưng tôi đã thấy nhiều cấp độ lồng nhau hơn và nó không thú vị

Làm thế nào để chúng tôi giải quyết điều này?

Các lựa chọn thay thế cho cuộc gọi lại

Bắt đầu với ES6, JavaScript đã giới thiệu một số tính năng giúp chúng tôi xử lý mã không đồng bộ không liên quan đến việc sử dụng lệnh gọi lại. Lời hứa [ES6] và Async/Await [ES2017]

Các ngôn ngữ lập trình như C, Java, C#, PHP, Go, Ruby, Swift và Python đều được mặc định là đồng bộ, một số trong số chúng xử lý không đồng bộ bằng cách sử dụng các luồng và sinh ra một quy trình mới

Đây là một ví dụ về mã đồng bộ

JScopy

1

Các dòng mã được thực thi nối tiếp nhau

Vì JavaScript được sinh ra bên trong trình duyệt nên công việc chính của nó ngay từ đầu là phản hồi các hành động của người dùng, như ________ 48, ________ 49, ________ 120, ________ 121, v.v. Làm sao nó có thể làm được điều này với mô hình lập trình đồng bộ?

Trong một số trường hợp, chẳng hạn như khi bạn muốn tìm nạp một số dữ liệu từ máy chủ [có thể mất một khoảng thời gian không xác định], việc chương trình của bạn bị đóng băng hoàn toàn trong khi đợi dữ liệu đó được tải xuống sẽ cực kỳ kém hiệu quả. . Vì vậy, thay vì làm điều đó, thông thường chỉ chạy tác vụ tìm nạp trong nền.
Điều này có nghĩa là nếu bạn có hai chức năng liên tiếp với chức năng A không đồng bộ thì chức năng B sẽ được thực thi trong khi chức năng A vẫn đang chạy. Trong trường hợp này nếu chức năng B phụ thuộc vào dữ liệu mà chức năng A đang tìm nạp, bạn sẽ gặp sự cố.

Không đồng bộ có nghĩa là mọi thứ có thể xảy ra độc lập với luồng chương trình chính

gọi lại

Vấn đề này được giải quyết với các cuộc gọi lại

Gọi lại là một hàm đơn giản được truyền dưới dạng giá trị cho một hàm khác và sẽ chỉ được thực thi khi sự kiện xảy ra.
Với hàm gọi lại, bạn có thể đảm bảo rằng hàm B chỉ được gọi sau khi hàm A hoàn thành công việc của nó vì hàm A thực sự là hàm chịu trách nhiệm gọi hàm B.

JScopy

2

Các cuộc gọi lại rất tốt cho các trường hợp đơn giản, tuy nhiên, mỗi cuộc gọi lại sẽ thêm một mức độ lồng nhau và khi bạn có nhiều cuộc gọi lại, mã bắt đầu trở nên phức tạp rất nhanh

JScopy

5

Đây chỉ là một mã 4 cấp độ đơn giản, nhưng bạn đã thấy nhiều cấp độ lồng nhau hơn và nó không vui chút nào

Bắt đầu với ES6, JavaScript đã giới thiệu một số tính năng giúp chúng tôi xử lý mã không đồng bộ không liên quan đến việc sử dụng lệnh gọi lại

lời hứa

lời hứa là một cách để giải quyết tình trạng khó xử khi gọi lại và ngăn việc viết quá nhiều lệnh gọi lại trong mã của bạn

Khi một lời hứa đã được gọi, nó sẽ bắt đầu ở trạng thái chờ xử lý. Điều này có nghĩa là chức năng người gọi tiếp tục thực thi, trong khi nó đợi lời hứa thực hiện quá trình xử lý của chính nó và cung cấp cho chức năng người gọi một số phản hồi

Tại thời điểm này, hàm gọi đợi nó trả về lời hứa ở trạng thái đã giải quyết hoặc ở trạng thái bị từ chối, nhưng hàm vẫn tiếp tục thực thi trong khi lời hứa thực hiện

Cú pháp hàm tạo cho một đối tượng lời hứa là

JScopy

6

Đối tượng

JScopy

22 kết quả có các thuộc tính bên trong

  • JScopy

    23 — ban đầu là “đang chờ xử lý”, sau đó thay đổi thành “đã thực hiện” hoặc “bị từ chối”,
  • JScopy

    24 — một giá trị tùy ý do bạn chọn, ban đầu là

    JScopy

    25

Khi người thi hành hoàn thành công việc, nó sẽ gọi một trong các hàm mà nó lấy làm đối số

  • JScopy

    26 — để chỉ ra rằng công việc đã hoàn thành thành công
  • đặt

    JScopy

    23 thành

    JScopy

    28,
  • đặt

    JScopy

    24 thành

    JScopy

    50
  • JScopy

    51 — để chỉ ra rằng đã xảy ra lỗi
  • đặt

    JScopy

    23 thành

    JScopy

    53,
  • đặt

    JScopy

    24 thành

    JScopy

    55

JScopy

56 và

JScopy

57 — các chức năng này được xác định trước bởi công cụ JavaScript. Vì vậy, chúng ta không cần phải tạo chúng. Thay vào đó, chúng ta nên viết trình thực thi để gọi chúng khi sẵn sàng

Đây là một ví dụ về hàm tạo Promise và hàm thực thi đơn giản

JScopy

3

Sau một giây “xử lý” người thi hành gọi

JScopy

58 để đưa ra kết quả

Đó là một ví dụ về việc hoàn thành công việc thành công, một “lời hứa được thực hiện”.
Và bây giờ hãy xem một ví dụ về việc người thi hành từ chối lời hứa có lỗi.

JScopy

5

Người thi hành nên làm một việc gì đó thường mất thời gian và sau đó gọi

JScopy

59 hoặc

JScopy

60 để thay đổi trạng thái của đối tượng Promise tương ứng

lời hứa có thể được tiêu thụ hoặc sử dụng

JScopy

8

Chạy

JScopy

61 sẽ thực hiện lời hứa của

JScopy

62 và sẽ đợi nó giải quyết, sử dụng hàm gọi lại

JScopy

63 và nếu có lỗi, nó sẽ xử lý nó trong hàm gọi lại

JScopy

64

Các lời hứa đã được đưa ra để giải quyết tình huống khó xử gọi lại nổi tiếng, nhưng chúng lại tự đưa ra sự phức tạp và độ phức tạp của cú pháp

Không đồng bộ/Đang chờ

Vì JavaScript không đồng bộ ES2017 thậm chí còn đơn giản hơn với cú pháp async/await

Chức năng không đồng bộ

Theo một cách thoải mái hơn, họ giảm bớt sự phức tạp xung quanh các lời hứa và giới hạn “không phá vỡ chuỗi” của các lời hứa xâu chuỗi. Nó dễ hiểu và dễ sử dụng một cách đáng ngạc nhiên

Từ khóa

JScopy

65 được đặt trước một hàm và từ khóa

JScopy

66 làm cho JavaScript đợi cho đến khi lời hứa đó được giải quyết và trả về kết quả của nó

JScopy

5

Việc thêm từ khóa

JScopy

65 vào bất kỳ chức năng nào có nghĩa là chức năng đó sẽ trả về một lời hứa và bao bọc những điều không hứa hẹn trong đó.

JScopy

66 theo nghĩa đen khiến JavaScript đợi cho đến khi lời hứa hoàn thành và sau đó tiếp tục với kết quả. Điều đó không tốn bất kỳ tài nguyên CPU nào, vì động cơ có thể thực hiện các công việc khác trong khi đó. thực thi các tập lệnh khác, xử lý các sự kiện, v.v.

Dưới đây là một số bài đăng trên blog yêu thích của tôi về Promises và Async/Await coding, nếu bạn đang muốn đọc thêm

JavaScript có thực sự không đồng bộ không?

JavaScript là ngôn ngữ lập trình đồng thời, không chặn, không đồng bộ, đơn luồng với nhiều tính linh hoạt.

JavaScript là đồng bộ hay không đồng bộ?

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ộ.

Các chức năng JavaScript có được đồng bộ hóa theo mặc định không?

JavaScript được đồng bộ hóa theo mặc định và là luồng đơn. Điều này có nghĩa là mã không thể tạo luồng mới và chạy song song.

JavaScript nào không đồng bộ?

JavaScript không đồng bộ. Mã không đồng bộ cho phép chương trình được thực thi ngay lập tức trong đó mã đồng bộ sẽ chặn việc thực thi thêm mã còn lại cho đến khi nó kết thúc mã hiện tại .

Chủ Đề