Gọi lại đồng bộ và không đồng bộ trong JavaScript

Trong bài viết này, tôi sẽ thảo luận về các hàm Gọi lại JavaScript với Không đồng bộ và đồng bộ với các ví dụ. Vui lòng đọc bài viết trước của chúng tôi, nơi chúng tôi đã thảo luận về chức năng JavaScript là công dân hạng nhất. Là một phần của bài viết này, chúng ta sẽ thảo luận về các gợi ý sau có liên quan đến các hàm Gọi lại JavaScript với Không đồng bộ và đồng bộ

  1. Tại sao chúng ta cần chức năng gọi lại?
  2. Gọi lại là gì?
  3. Khi nào sử dụng chức năng gọi lại trong JavaScript?
  4. Hàm gọi lại đồng bộ JavaScript
  5. Hàm gọi lại không đồng bộ JavaScript
  6. Hàm gọi lại JavaScript với từ khóa này
  7. Gọi lại JavaScript dưới dạng một chức năng ẩn danh
  8. Gọi lại JavaScript dưới dạng chức năng mũi tên
  9. Gọi lại dưới dạng khai báo sự kiện
  10. Xử lý lỗi trong Hàm gọi lại JavaScript
  11. Cách tránh Callback Hell/Kim tự tháp diệt vong
  12. Gọi lại Javascript vs Đóng cửa
Tại sao chúng ta cần chức năng gọi lại?

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ơn

    JavaScript 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”] 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ụ 1

    JavaScript 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ụ-2

    JavaScript 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ày

Thô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ày

    JavaScript 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ện

Như 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 JavaScript

Gọ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

Địa ngục gọi lại JavaScript [Kim tự tháp diệt vong] và các cuộc gọi lại lồng nhau

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 vong

    JavaScript 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
Gọi lại Javascript vs Đóng cửa

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ộ

Gọi lại đồng bộ và không đồng bộ là gì?

Sự khác biệt chính giữa lệnh gọi lại đồng bộ và không đồng bộ là các lệnh gọi lại đồng bộ được thực thi ngay lập tức, trong khi việc thực thi các lệnh gọi lại không đồng bộ được hoãn lại vào thời điểm sau đó.

Sự khác biệt giữa không đồng bộ và đồng bộ trong JavaScript là gì?

Không đồng bộ là một kiến ​​trúc không chặn, vì vậy việc thực thi một tác vụ không phụ thuộc vào tác vụ khác. Nhiệm vụ có thể chạy đồng thời. Đồng bộ là một kiến ​​trúc chặn, vì vậy việc thực hiện từng thao tác phụ thuộc vào việc hoàn thành thao tác trước nó

Các cuộc gọi lại JavaScript có không đồng bộ không?

Gọi lại về bản chất không phải là không đồng bộ, nhưng có thể được sử dụng cho mục đích không đồng bộ . Trong đoạn mã này, bạn định nghĩa một hàm fn , định nghĩa một hàmhigherOrderFunction nhận hàm gọi lại làm đối số và chuyển fn làm hàm gọi lại tớihigherOrderFunction.

Sự khác biệt giữa async và gọi lại là gì?

Về cơ bản - nếu một cuộc gọi lại thực hiện tất cả thì nó hoạt động trước khi quay lại người gọi, thì đó là "đồng bộ". Nếu nó có thể quay lại trình gọi ngay sau khi được gọi - và trình gọi và lệnh gọi lại có thể hoạt động song song - thì đó là "không đồng bộ"

Chủ Đề