- Tại sao chúng ta cần chức năng gọi lại?
- Gọi lại là gì?
- Khi nào sử dụng chức năng gọi lại trong JavaScript?
- Hàm gọi lại đồng bộ JavaScript
- Hàm gọi lại không đồng bộ JavaScript
- Hàm gọi lại JavaScript với từ khóa này
- Gọi lại JavaScript dưới dạng một chức năng ẩn danh
- Gọi lại JavaScript dưới dạng chức năng mũi tên
- Gọi lại dưới dạng khai báo sự kiện
- Xử lý lỗi trong Hàm gọi lại JavaScript
- Cách tránh Callback Hell/Kim tự tháp diệt vong
- Gọi lại Javascript vs Đóng cửa
Như chúng ta biết rằng JavaScript là một ngôn ngữ kịch bản đơn luồng. Hầu hết thời gian, mã JavaScript chạy đồng bộ. Điều đó có nghĩa là đầu tiên dòng mã đầu tiên được thực thi, sau đó mã dòng tiếp theo được thực thi, v.v.
Như chúng ta đã biết rằng JavaScript là tập lệnh phía máy khách nên khi JavaScript phía máy khách chạy trong trình duyệt web và quy trình chính của trình duyệt là một vòng lặp sự kiện đơn luồng. Nếu chúng tôi cố gắng chạy các hoạt động dài hạn trong một vòng lặp sự kiện đơn luồng, quy trình sẽ bị chặn. Điều này kém về mặt kỹ thuật vì quy trình ngừng xử lý các sự kiện khác trong khi chờ thao tác của bạn hoàn tất
Mọi thứ đều như chúng ta mong đợi và cách nó hoạt động trong hầu hết các ngôn ngữ lập trình. Tuy nhiên, có những lúc chúng ta không thể ngồi đợi một dòng mã thực thi. Chúng tôi không thể đợi 2 giây để tải một tệp lớn và dừng chương trình hoàn toàn. Chúng ta không thể đợi tài nguyên mạng được tải xuống rồi mới làm việc khác. JavaScript giải quyết vấn đề này bằng cách sử dụng lệnh gọi lại
Ví dụ: câu lệnh "cảnh báo" hiển thị hộp cảnh báo được tìm thấy dưới dạng một trong các mã chặn trong JavaScript trong trình duyệt. Nếu chúng tôi chạy một câu lệnh cảnh báo, nó sẽ hiển thị hộp cảnh báo, sau đó chúng tôi không thể thực hiện bất kỳ tương tác/thao tác nào trong trình duyệt cho đến khi chúng tôi đóng cửa sổ hộp thoại cảnh báo. Để tránh bị chặn trong các hoạt động chạy dài, một cuộc gọi lại xuất hiện trong bức tranh này và được sử dụng
Hãy xem một số ví dụ để hiểu nó tốt hơnJavaScript example without callback function getMessage[] { console.log["get message"]; } function showMessage[] { console.log["show message"]; } getMessage[]; showMessage[];
đầu ra
Trong ví dụ trên, hàm getMessage[] được thực thi trước rồi đến hàm displayMessage[] được thực thi. Cả hai hàm đều hiển thị một thông báo trong cửa sổ bảng điều khiển của trình duyệt và cả hai đều được thực thi ngay lập tức sau cái kia
Giả sử có một tình huống mà một số mã không được thực thi ngay lập tức. Chúng ta có thể suy nghĩ về làm thế nào? . Trong điều kiện như vậy làm thế nào chúng ta sẽ có thể đối phó với nó?
Gọi lại là gì?Theo MDN. Hàm gọi lại là một hàm được truyền vào một hàm khác dưới dạng đối số, sau đó hàm này được gọi bên trong hàm bên ngoài để hoàn thành một số loại quy trình hoặc hành động
Hàm gọi lại có thể đồng bộ hoặc không đồng bộ. Hàm gọi lại như tên ngụ ý là hàm được thực thi sau khi hàm khác thực thi xong. Gọi lại là một hàm được truyền dưới dạng tham số vào một hàm khác sẽ được thực thi sau đó để thực hiện một số thao tác. Hàm gọi lại được thực thi không đồng bộ.
Khi nào sử dụng chức năng gọi lại trong JavaScript?Hàm gọi lại được sử dụng trong một số tác vụ như
- khi làm việc với hệ thống tệp [tải xuống hoặc tải lên],
- Gửi yêu cầu mạng để nhận một số tài nguyên như tệp kiểm tra hoặc tệp nhị phân từ máy chủ,
- sự kiện,
- DOM trong trình duyệt
- hoặc làm việc với các API web để tìm nạp dữ liệu
Để xử lý tình huống trên chúng ta phải sử dụng cách ghi code bất đồng bộ sử dụng hàm callback. Như chúng ta biết rằng chức năng gọi lại về bản chất là không đồng bộ
Một trong những ví dụ đơn giản nhất về cách sử dụng gọi lại là bộ hẹn giờ. Bộ hẹn giờ không phải là một phần của JavaScript, nhưng chúng được cung cấp bởi trình duyệt. Hãy để tôi nói về một trong những đồng hồ hẹn giờ mà chúng ta có. setTimeout[]
Hàm setTimeout[] chấp nhận 2 đối số. một chức năng, và một số. Số là mili giây phải vượt qua trước khi chức năng được chạy. setTimeout[] là hàm không đồng bộ JavaScript thực thi khối mã hoặc đánh giá biểu thức thông qua hàm gọi lại sau độ trễ được đặt tính bằng mili giây
Ví dụJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]
đầu ra
Trong hàm ví dụ trên có chứa bảng điều khiển . log[‘Hello callback setTimeout’] sẽ được thực thi sau 3 giây. Khi thêm bảng điều khiển . log[“hi”] và bảng điều khiển. log[“bye”] chúng ta có thể thấy điều gì đang xảy ra.
Gọi lại JavaScript đồng bộCuộc gọi lại có thể được sử dụng để thực thi mã sau khi thực thi phương thức kết thúc
Ví dụ 1JavaScript Callback synchronous example1 function doSomething[then] { console.log['call first']; then[]; } // call first, then execute callback to log 'done' doSomething[function [] { console.log['Done']; }]; console.log['call second'];
đầu ra
Trong ví dụ đồng bộ ở trên, phương thức doS Something [] ở trên thực thi đồng bộ với hàm gọi lại – các khối thực thi cho đến khi hàm doS Something [] trả về, đảm bảo rằng hàm gọi lại được thực thi trước khi trình thông dịch tiếp tục
Ví dụ-2JavaScript Callback synchronously example2 function greeting[name] { alert['Hello ' + name]; } function takeUserInput[callback] { var name = prompt['Please enter your name.']; callback[name]; } takeUserInput[greeting];
đầu ra
Trong ví dụ trên, hàm takeUserInput[lời chào] thực thi mã một cách đồng bộ với hàm gọi lại
Gọi lại JavaScript không đồng bộGọi lại cũng có thể được sử dụng để thực thi mã không đồng bộ. Một ví dụ được đưa ra dưới đây
JavaScript Callback synchronous example function doSomethingAsync[then] { setTimeout[then, 1000]; console.log['call first asynchronously']; } doSomethingAsync[function [] { console.log['Done']; }]; console.log['call second'];
đầu ra
Trong ví dụ không đồng bộ ở trên, các lệnh gọi lại then được coi là phần tiếp theo của các phương thức doSomething[]. Cung cấp một cuộc gọi lại dưới dạng lệnh cuối cùng trong một chức năng được gọi là cuộc gọi đuôi, được tối ưu hóa bởi trình thông dịch ES2015
Hàm gọi lại thường được sử dụng để tiếp tục thực thi mã ngay cả sau khi một hành động không đồng bộ đã hoàn thành, chúng được gọi là gọi lại không đồng bộ. Một ví dụ là chức năng gọi lại thực thi bên trong a, sau đó chặn chuỗi vào cuối lời hứa sau khi lời hứa đó hoàn thành hoặc từ chối
Hàm gọi lại JavaScript với từ khóa nàyThông thường, khi sử dụng gọi lại, chúng tôi muốn truy cập vào một ngữ cảnh cụ thể
Ví dụ. gọi lại với từ khóa nàyJavaScript Callback asynchronously with this keyword example function SomeClass[msg, elem] { this.msg = msg; elem.addEventListener['click', function [] { console.log[this.msg]; // { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]0
đầu ra
Trong ví dụ về mũi tên ở trên, hàm gọi lại function[x]{console. log[x]} được rút gọn thành x=>console. nhật ký[x]
Gọi lại dưới dạng khai báo sự kiệnNhư chúng ta biết rằng JavaScript là ngôn ngữ lập trình hướng sự kiện. Chúng ta cũng có thể sử dụng các hàm gọi lại để khai báo một sự kiện. Ví dụ: giả sử chúng tôi muốn người dùng nhấp vào nút
Ví dụJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]1
đầu ra
Trong ví dụ trên, chúng tôi đã chọn nút có id của nó, sau đó chúng tôi đã thêm trình xử lý sự kiện bằng phương thức addEventListener. Cần 2 tham số. Tham số đầu tiên là loại của nó, “nhấp chuột” và tham số thứ hai là chức năng gọi lại, hiển thị thông báo trong bảng điều khiển của trình duyệt khi nhấp vào nút. Như chúng ta có thể thấy, hàm gọi lại cũng được sử dụng để khai báo sự kiện trong JavaScript
Xử lý lỗi trong Hàm gọi lại JavaScriptGọi lại thường được sử dụng để cung cấp xử lý lỗi. Đây là một định dạng của luồng điều khiển, trong đó một số lệnh chỉ được thực thi khi xảy ra lỗi. Đoạn mã sau giới thiệu hai cuộc gọi lại. thành công và thất bại để xử lý các trường hợp thành công và thất bại tương ứng
Ví dụ. Gọi lại JavaScript-Xử lý lỗi đồng bộJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]2
đầu ra
Trong ví dụ trên, việc thực thi mã trong compareData[] ở trên có thể có hai nhánh. thành công khi giá trị kỳ vọng và giá trị thực tế giống nhau và lỗi khi chúng khác nhau. Điều này hữu ích khi luồng điều khiển sẽ bị tách ra sau một số hoạt động không đồng bộ
Ví dụ. Gọi lại JavaScript-Xử lý lỗi không đồng bộJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]3
đầu ra
Hãy lấy một ví dụ khác về việc tải tệp xuống. Hàm fileDownload[] giả định rằng mọi thứ đều hoạt động tốt và không xem xét bất kỳ trường hợp ngoại lệ nào. Đoạn mã sau giới thiệu hai cuộc gọi lại. thành công và thất bại để xử lý các trường hợp thành công và thất bại tương ứng.
Ví dụ. Gọi lại JavaScript-Tệp xử lý lỗi Tải xuống không đồng bộJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]4
đầu ra
Việc lồng nhiều hàm không đồng bộ bên trong các lệnh gọi lại được gọi là kim tự tháp diệt vong hoặc địa ngục lệnh gọi lại
Ví dụ. Gọi lại lồng nhau và địa ngục gọi lại
JavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]5
Địa ngục cuộc gọi lại xảy ra khi có nhiều chức năng không đồng bộ được thực thi lần lượt. Nó còn được gọi là kim tự tháp diệt vong
Xem xét ví dụ về chương trình fileDownload[] trước đóGiả sử chúng ta cần tải xuống nhiều hình ảnh liên tục. Làm cách nào để chúng tôi tải xuống nhiều ảnh và xử lý chúng tuần tự? . Để triển khai chức năng tương tự với sự trợ giúp của lệnh gọi lại, đoạn mã sẽ trông như thế này.
Ví dụ. Địa ngục gọi lại JavaScript hoặc Kim tự tháp diệt vongJavaScript callback with setTimeout example console.log["hi"] setTimeout[[] => { // runs after 3 seconds console.log['Hello callback setTimeout function'] }, 3000] console.log["bye"]6
đầu ra
Mã ví dụ trên hoạt động tốt. Tuy nhiên, chức năng gọi lại này không mở rộng tốt khi độ phức tạp tăng lên. Từ đoạn mã trên, chúng ta có thể thấy mã trở nên khó hiểu hơn, khó bảo trì hơn và cũng khó sửa đổi hơn. Điều này xảy ra với việc lồng tất cả các hàm gọi lại.
Cách tránh Callback Hell/Kim tự tháp diệt vongđể tránh địa ngục gọi lại hoặc kim tự tháp diệt vong, chúng ta có thể sử dụng nhiều kỹ thuật như sau
- Bằng cách sử dụng lời hứa
- Bằng cách sử dụng chức năng async/await
Khép kín
- Trong JavaScript, bao đóng là một biểu thức được gán cho một biến, có thể được truyền dưới dạng đối số cho hàm hoặc được trả về dưới dạng kết quả của hàm
- Các bao đóng cho phép chúng ta truy cập vào phạm vi của chức năng bên ngoài từ một chức năng bên trong
- Closure đề cập đến cách một chức năng đóng trên phạm vi từ vựng của nó. Do đó, chức năng đã đóng cửa
Gọi lại
- Gọi lại là một khái niệm tương tự như đóng cửa. Hàm gọi lại là một hàm được truyền dưới dạng tham số cho một hàm khác để thực thi sau. Trong khi trong quá trình thực thi mã, hàm được gọi sẽ thực thi hàm được truyền dưới dạng đối số, đây được gọi là gọi lại. Nó được gọi bên trong chức năng khác
- Một trường hợp sử dụng chính của điều này là hiệu suất của các hoạt động không đồng bộ bằng cách đưa một hàm vào hàng đợi sự kiện thời gian chạy
- Gọi lại là một chức năng cuối cùng được gọi trở lại phạm vi gọi. Do đó, nó được gọi là một cuộc gọi lại
Trong bài viết tiếp theo, tôi sẽ thảo luận về Hàm ẩn danh JavaScript với các ví dụ. Ở đây, trong bài viết này, tôi cố gắng giải thích chức năng Gọi lại JavaScript với Không đồng bộ và đồng bộ với các ví dụ. Tôi hy vọng chức năng Gọi lại JavaScript này với bài viết Không đồng bộ và đồng bộ sẽ giúp ích cho bạn khi cần. Tôi muốn có phản hồi của bạn. Vui lòng gửi phản hồi, câu hỏi hoặc nhận xét của bạn về chức năng Gọi lại JavaScript này với Không đồng bộ và đồng bộ