Một cuộc thảo luận về Node Modules là
không đầy đủ mà không nói về Callbacks và xử lý lỗi.
callbacks là gì và tại sao họ cần thiết để
hỗ trợ tính toán không đồng bộ là rất
hữu ích khi chúng tôi viết các ứng dụng Node.js?
Xử lý lỗi được thực hiện như thế nào trong các ứng dụng Node?
Chúng ta hãy nói ngắn gọn về những điều này trong bài giảng này.
Trước khi chúng ta tiếp tục nói về Node Modules và Callbacks,
chúng ta cần phải hiểu hai tính năng nổi bật về ngôn ngữ JavaScript chính nó.
Đầu tiên và quan trọng nhất, JavaScript hỗ trợ những gì được gọi là hàm hạng nhất.
Chúng ta có ý nghĩa gì của các chức năng hạng nhất?
Đó là một chức năng có thể được xử lý giống như bất kỳ biến khác.
Và do đó, các hàm có thể được truyền lại như các
tham số bên trong các cuộc gọi hàm đến các hàm khác.
Và điều đó về cơ bản cho phép chúng tôi gửi các chức năng như hàm callback có thể được
gọi từ một module Node khác để có được một số công việc hoàn thành.
Sau đó nhìn vào cách này là rất hữu ích trong việc hỗ trợ callbacks trong Node.js.
Khía cạnh thứ hai về JavaScript là sự hỗ trợ cho Closures.
Những gì chúng tôi có ý nghĩa của Closures?
Đặc biệt, nếu bạn đã quen thuộc với các ngôn ngữ lập trình chức năng,
bạn sẽ hiểu cách đóng cửa hoạt động.
Một hàm được định nghĩa bên trong một hàm khác
sẽ tự động truy cập vào các biến được khai báo trong hàm bên ngoài.
Vì vậy, ngay cả khi hàm bên ngoài được thực thi hoàn tất,
khi hàm bên trong thực thi sau này hàm bên trong vẫn sẽ có quyền truy cập vào
các giá trị của các biến bên trong hàm bên ngoài đó.
Và đây là một lần nữa,
rất hiệu quả được sử dụng khi chúng ta sử dụng Callbacks trong các ứng dụng Node.
Nếu bạn đã quen với cách viết tiêu chuẩn các ứng dụng,
thì bạn đã quen thuộc với tính toán đồng bộ, nơi bạn
chỉ định một tính toán như một tập hợp các bước cần thực hiện cái khác.
Bây giờ, nếu bạn tổ chức tính toán của bạn như sau,
như được hiển thị ở phía bên trái của slide ở đây,
chúng tôi có tính toán một sau đó là một tính toán chạy dài,
tiếp theo là tính toán hai, và tính toán ba.
Vì vậy, trong sự sắp xếp này,
chúng ta hãy giả định rằng tính toán hai là phụ
thuộc vào tính toán chạy dài hoàn thành công việc của nó,
sau đó nó có ý nghĩa cho tính toán hai để chờ cho đến khi
tính toán chạy dài được hoàn thành trước khi nó được thực hiện.
Bây giờ, chúng ta có thể có một phần khác của công việc
được thực hiện được định nghĩa bởi tính toán ba.
Tính toán ba có thể là trong noway phụ thuộc vào tính toán hai,
hoặc tính toán chạy dài để hoàn thành trước khi nó được thực hiện.
Vì vậy, trong trường hợp này,
nếu chúng ta thực hiện đồng bộ của tính toán này,
sau đó tính toán ba sẽ bị mắc kẹt,
mặc dù nó không phải là cách nào phụ thuộc vào việc hoàn thành một
trong hai tính toán hai, hoặc tính toán chạy dài.
Vì vậy, do đó, số lượng công việc phải được thực hiện bằng cách tính toán ba,
sẽ bị trì hoãn vì không có lý do của nó, đúng không?
Thay vào đó bị trì hoãn vì một cái gì đó đứng trước nó trong trình tự tính toán.
Bây giờ, tính toán không đồng bộ, chúng ta có thể sắp xếp lại công việc này
theo cách mà tính toán một, khi nó hoàn thành,
có thể sinh ra những tính toán chạy dài để được thực hiện sau hậu trường một cách độc lập,
và kể từ khi tính toán hai phụ thuộc vào tính toán chạy dài để kết thúc,
sau đó tính toán hai có thể được thực hiện khi tính toán chạy dài kết thúc.
Bây giờ, điều này giải phóng tính toán ba để tiếp tục,
ngay sau khi tính toán một kết thúc.
Vì vậy, cách sắp xếp này,
đảm bảo rằng tính toán ba sẽ kết thúc nhanh hơn nhiều so với
bị mắc kẹt phía sau tính toán chạy dài, và tính toán hai.
Vì vậy, cách tiếp cận này của sắp xếp lại công việc của bạn là rất hữu ích đặc biệt,
khi bạn có một tính toán chạy dài đặc biệt,
I/O ràng buộc tính toán để được thực hiện.
Vì vậy, trong trường hợp này, bạn có thể đẻ ra khỏi I/O ràng buộc tính toán,
và khi hoàn thành,
sau đó bất cứ điều gì cần phải được thực hiện sau đó,
có thể được gửi đến nó như một Callback.
Vì vậy, tính toán hai sẽ được biến thành
một Callback và sau đó đưa ra cho tính toán chạy dài.
Vì vậy, khi điều đó hoàn thành công việc của
nó, sau đó nó sẽ gọi lại các chức năng được bao bọc bên trong callback.
Vì vậy, điều này được tận dụng rất hiệu quả bởi Node.js
trong việc sắp xếp lại các tính toán trong các ứng dụng Node của chúng tôi.
Bây giờ, điều này rất,
rất hữu ích khi chúng ta nhìn vào cách Node.js chạy.
Vì vậy, như chúng tôi nhận ra,
Node.js được tổ chức thành một vòng lặp sự kiện luồng duy nhất.
Vòng lặp sự kiện duy nhất luồng này về cơ bản,
chọn lên yêu cầu khi họ đi vào và thực hiện nó cái khác.
Bất cứ khi nào nó cần phải đẻ ra một yêu cầu I/O,
yêu cầu I/O sẽ được đẻ ra,
và bất kỳ công việc cần phải được thực hiện sau khi yêu cầu I/O được hoàn thành,
sẽ được kèm theo bên trong một Callback.
Vì vậy, khi yêu cầu I/O hoàn tất,
sau đó nó sẽ đặt Callback vào hàng đợi yêu cầu,
và Callback sẽ được xử lý sau đó,
bởi vòng lặp sự kiện.
Vì vậy, vòng lặp sự kiện là một vòng lặp chạy liên tục
mà về cơ bản chọn lên yêu cầu từ hàng đợi yêu cầu,
và sau đó dịch vụ chúng một tại một thời điểm.
Vì vậy, khi bạn nghĩ lại về nó,
bạn nhận ra rằng Node.js là một luồng duy nhất,
nhưng đồng thời,
nó có thể đạt được tốc độ nhanh hơn nhiều của hoàn thành công việc,
chỉ đơn giản là vì việc sử dụng khôn ngoan của callbacks,
và thực hiện không đồng bộ của I/O yêu cầu,
như cho tập tin truy cập hoặc cơ sở dữ liệu,
hoặc xử lý chạy dài có thể được thực hiện độc lập đằng sau hậu trường.
Bây giờ, cách vòng lặp sự kiện Node.js xử lý tất cả điều này,
là vòng lặp sự kiện được sắp xếp trong một chuỗi các giai đoạn.
Vì vậy, như bạn thấy trong sơ đồ hiển thị ở đây,
các giai đoạn bao gồm xử lý hẹn giờ,
I/O gọi lại xử lý, sau đó bạn có nhàn rỗi, chuẩn bị,
sau đó cuộc thăm dò nơi các yêu cầu đến cho các kết nối hoặc dữ liệu được xử lý,
và sau đó giai đoạn kiểm tra,
và sau đó cuối cùng, giai đoạn callbacks đóng.
Bây giờ, một số chi tiết về những gì được thực hiện trong mỗi giai đoạn này được liệt kê ở phía bên phải.
Trong giai đoạn hẹn giờ,
vòng lặp sự kiện xử lý bất cứ điều gì được kích hoạt bởi
hàm setTimeout () trong JavaScript.
I/O callbacks được thực hiện,
hầu như tất cả các callbacks mà trở lại để được
thực hiện sau khi một yêu cầu I/O sẽ được xử lý bởi hàng đợi I/O callbacks.
Vì vậy, mỗi giai đoạn duy trì riêng của mình hàng đợi riêng biệt,
và vòng lặp sự kiện Node.js chọn lên yêu cầu từ mỗi hàng đợi, và xử lý chúng.
Các, nhàn rỗi, chuẩn bị, có nghĩa là để sử dụng nội bộ bởi Node.js.
Cuộc thăm dò là nơi nó lấy các sự kiện I/O mới được xử lý và có lẽ,
các yêu cầu đến từ bên ngoài.
Giai đoạn gọi lại đóng xử lý bất kỳ đóng cửa ổ cắm nào cần được xử lý, v.v.
Bây giờ, chúng ta không cần phải lo lắng quá nhiều về
tất cả các chi tiết này nếu chúng ta cần phải thực sự viết một ứng dụng Node.js.
Khi được yêu cầu, chúng tôi sẽ xem xét một số chi tiết này như và khi nào
nó là cần thiết để hiểu cách ứng dụng Node của chúng tôi hoạt động.
Nhưng cho thời điểm này, điều này cung cấp cho bạn một hình ảnh lớn
như thế nào các vòng lặp sự kiện Node.js được xử lý.
Đủ để nói rằng đây là đủ thông tin để chúng ta
hiểu được các ứng dụng Node và cách chúng hoạt động cho thời điểm này.
Nếu bạn muốn biết thêm chi tiết,
sau đó tôi đã cung cấp cho bạn một liên kết đến một mô tả chi tiết trong
tài liệu Node.js mà giải thích về vòng lặp sự kiện chi tiết hơn.
Với sự hiểu biết nhanh chóng về Node,
Callbacks, và xử lý lỗi,
chúng ta sẽ chuyển sang bài tập,
nơi chúng ta sẽ xem xét cách một ứng dụng Node có thể viết bằng Callbacks,
và cách xử lý lỗi bên trong ứng dụng Node.
Chúng ta sẽ thấy việc sử dụng lặp đi lặp lại mô hình này trong các bài tập
tiếp theo, và các bài học tiếp theo cụ thể,
khi chúng ta nhìn vào Express,
và cách chúng ta xây dựng các ứng dụng phía máy chủ sử dụng Express
chi tiết hơn trong phần sau của khóa học này.