Điều gì xác định chức năng Javascript nào đang chặn so với không chặn?


27

Tôi đã làm Javascript dựa trên web (vanilla JS, jQuery, Backbone, v.v.) trong vài năm nay và gần đây tôi đã làm một số công việc với Node.js. Phải mất một thời gian tôi mới hiểu được lập trình "không chặn", nhưng giờ tôi đã quen với việc sử dụng các cuộc gọi lại cho các hoạt động IO và không có gì.

Tôi hiểu rằng Javascript là một luồng đơn. Tôi hiểu khái niệm về "hàng đợi sự kiện" của Node. Điều tôi không hiểu là điều gì quyết định liệu một hoạt động javascript riêng lẻ có "chặn" so với "không chặn" hay không. Làm cách nào để biết tôi có thể sử dụng đồng bộ các thao tác nào để tạo đầu ra một cách đồng bộ để tôi sử dụng mã sau và những thao tác nào tôi cần chuyển lại cuộc gọi để tôi có thể xử lý đầu ra sau khi hoàn thành thao tác ban đầu? Có một danh sách các chức năng Javascript ở đâu đó không đồng bộ / không chặn và một danh sách các chức năng đồng bộ / chặn không? Điều gì đang ngăn ứng dụng Javascript của tôi trở thành một điều kiện cuộc đua khổng lồ?

Tôi biết rằng các hoạt động mất nhiều thời gian, như các hoạt động IO trong các hoạt động Node và AJAX trên web, yêu cầu chúng không đồng bộ và do đó sử dụng các cuộc gọi lại - nhưng ai đang xác định điều gì đủ điều kiện là "một thời gian dài"? Có một số loại kích hoạt trong các hoạt động này loại bỏ chúng khỏi "hàng đợi sự kiện" bình thường? Nếu không, điều gì làm cho chúng khác với các hoạt động đơn giản như gán giá trị cho các biến hoặc lặp qua các mảng, mà dường như chúng ta có thể phụ thuộc vào để hoàn thành một cách đồng bộ?

Có lẽ tôi thậm chí không nghĩ về điều này một cách chính xác - hy vọng ai đó có thể khiến tôi thẳng tiến. Cảm ơn!


đây là điều tôi thấy thực sự hữu ích, mặc dù câu trả lời cho câu hỏi của bạn là bạn phải kiểm tra tài liệu để tìm hiểu xem các phương thức có đồng bộ không.
Anastasios Andronidis

Câu trả lời:


13

Nói chung, bất kỳ chức năng nào kết nối mạng hoặc sử dụng bộ định thời để thực hiện mọi việc trong một khoảng thời gian sẽ không đồng bộ.

Nếu chức năng thực hiện một cuộc gọi lại, bạn có thể xem xét cuộc gọi lại được sử dụng để làm gì và thông thường nó sẽ rõ ràng cho dù có không đồng bộ hay không. Nếu chức năng không cung cấp một cuộc gọi lại, thì nó không có cách nào để truyền đạt kết quả không đồng bộ nên có lẽ nó không đồng bộ.

Không có cách nào để nói chắc chắn. Nó phải được đánh vần trong tài liệu cho một chức năng hoặc rõ ràng từ cách giao diện hoạt động.

Các hoạt động không đồng bộ khác nhau dưới vỏ bọc so với các hoạt động đồng bộ trong đó các hoạt động không đồng bộ có khái niệm thiết lập một hoạt động, bắt đầu hoạt động và sau đó được thông báo về tiến trình, hoàn thành hoặc lỗi trong hoạt động. Lặp lại một mảng là một hoạt động đồng bộ. Nó không có những vấn đề này. Mã chỉ chạy đồng bộ. Phát hành một cuộc gọi ajax bao gồm đăng ký một cuộc gọi lại cho các thông báo trạng thái, sau đó bắt đầu cuộc gọi ajax, sau đó tiếp tục chạy các javascript khác và sau đó một thời gian, cuộc gọi lại được gọi với một thay đổi trạng thái của cuộc gọi ajax (chẳng hạn như hoàn thành).


1
Là một lưu ý bổ sung, một số chức năng Javascript vừa chặn vừa không chặn, tùy thuộc vào tham số của chúng. Ví dụ, XMLHttpRequest.opencó một asynctham số boolean kiểm soát xem cuộc gọi sau này sendcó đồng bộ hay không.
Brian

Tôi chỉ không thấy câu trả lời này hữu ích và thường được giải thích.
Mehdi Raash

@MehdiRaash - Câu trả lời là bạn tìm ra nó từ tài liệu hoặc từ giao diện. Không có cách nào khác. Đó là những gì nó nói. Không chắc chắn những gì bạn đang mong đợi. Không có câu trả lời viên đạn ma thuật.
jfriend00

6

Từ những gì tôi hiểu, bạn không hỏi về những gì bạn nên làm cho không đồng bộ nhưng làm thế nào để biết một chức năng không đồng bộ.

Bạn kiểm tra tài liệu. Nghiêm túc - đó là những gì nó làm. Bạn không đoán được chức năng nào dựa trên tên của nó hoặc bối cảnh của nó giống như vậy. Nếu bạn không chắc chắn và có quyền truy cập vào mã nguồn của nó, bạn hãy kiểm tra xem.

Đó là cách duy nhất hoàn toàn đáng tin cậy.

Bây giờ để đoán.

  • Nếu nó chấp nhận một cuộc gọi lại hoặc trả lại một lời hứa thì có lẽ nó không đồng bộ (tôi đã thấy ngoại lệ cho quy tắc đó)
  • Nói chung, mọi thứ liên quan đến I / O trong node.js và nói chung là trong JavaScript đều được thực hiện không đồng bộ (tôi cũng đã thấy ngoại lệ cho quy tắc đó)

4

Vì JavaScript là luồng đơn nên tất cả các khối xử lý cho đến khi xảy ra một trong những điều sau đây

1) Việc thực thi hiện tại yêu cầu một dịch vụ bên ngoài, chẳng hạn như I / O hoặc yêu cầu kết nối mạng hoặc yêu cầu webworker

2) Một cuộc gọi chức năng được đặt trên bộ hẹn giờ sẽ được thực hiện sau đó

Không có danh sách các chức năng chặn / không chặn. Bạn nên kiểm tra tài liệu.

Ứng dụng của bạn có thể gặp phải tình trạng chủng tộc nếu nhiều dịch vụ bên ngoài có khóa trên luồng javascript và cố gắng truy cập cùng lúc. Các trình duyệt hiện đại và công cụ V8 xử lý việc này, nhưng bạn có thể gặp phải tình trạng cuộc đua này nếu bạn sử dụng phonegap và viết ứng dụng javascript cho thiết bị di động. Sự hỗ trợ không có ở đó để xử lý các điều kiện cuộc đua.

Nói chung, giả sử các khối mã trừ khi có một cuộc gọi lại. Và ngay cả khi có một cuộc gọi lại, điều đó không có nghĩa là nó sẽ không chặn.


-1

Tôi cũng chưa quen với node.js (và JavaScript nói chung) và tôi không quen với quá nhiều mã không đồng bộ. Tôi chỉ muốn chỉ ra rằng trong Tổng quan về Chặn so với Không chặn trên nodejs.org, nó nói rằng:

Tất cả các phương thức I / O trong thư viện chuẩn Node.js cung cấp các phiên bản không đồng bộ, không chặn và chấp nhận các hàm gọi lại. Một số phương thức cũng có các đối tác chặn, có tên kết thúc bằng Sync.


1
Làm thế nào để giải quyết câu hỏi này? Xem cách trả lời
gnat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.