Callback trong javascript

Callback là một khái niệm không mới. Tuy nhiên, nó là một trong những khái niệm khá lằng ngoằng và dễ nhầm lẫn trong lập trình. Với 1 số bạn có basic về C++, Java hay C#, ta thường biết đến callback qua khái niệm delegate (con trỏ hàm).

Bài viết đầu tiên, mình xin giới thiệu callback trong javascript. Lý do chọn javascript là vì Callback trong javascript là đơn giản, dễ hiểu nhất. Bài viết nhắm tới đối tượng là các bạn beginner nên mình sẽ cố gắng viết đơn giản nhất có thể.

1. Khái niệm về callback

Đầu tiên, xin nhắc lại đôi chút về khá niệm callback:

A callback is a piece of executable code that is passed as 
an argument to other code, which is expected to call back
(execute) the argument at some convenient time.

Nói một cách dễ hiểu, callback tức là ta truyền một đoạn code (Hàm A) này vào một đoạn code khác (Hàm B). Tới một thời điểm nào đó, Hàm A sẽ được hàm B gọi lại (callback).

Tới đây các bạn vẫn chưa hiểu? Ok, ngày xưa khi nghe các giáo viên dạy cái này mình cũng ko hiểu gì cả =))). Mình xin đưa ra 1 ví dụ đơn giản dễ hiểu ở phần dưới.

why1

2. Ví dụ của callback. Ứng dụng trong jQuery

Bạn có việc phải đi công tác xa nhà.  Bạn dặn vợ, trong thời gian bạn đi, nếu như có ai giao quà tới, hãy đem qua tặng em gái dễ thương hàng xóm. Hàm A ở đây là việc tặng quà cho em hàng xóm:


function tangQua(qua) {
   return console.log("Đã tặng " + qua);  
}

Hàm B ở đây là việc vợ bạn ở nhà. Ta truyền hàm A vào như 1 argument cho hàm B, tại 1 thời điểm nào đó, hàm B sẽ gọi hàm A (Tức là vợ bạn mang quà qua cho em hàng xóm).


function oNha(vo, tangQua) {
   var qua = "Quà đã nhận";
   tangQua(qua);  
}

Như các bạn thấy, hàm A được truyền vào như 1 argument. Các bạn biết jQuery có thể sử dụng rất nhiều callback mà ko biết. Hãy xét ví dụ dưới đây, ta hiển thị 1 pop-up khi click vào 1 button. Bài viết trước nói về fiddle nên lần này mình sẽ đưa link fiddle làm ví dụ:

http://jsbin.com/potivubifi/1/watch?html,js,output

Ở đây, function showPopup chính là hàm A, còn $(‘#btn’).click() là hàm B. Hàm B sẽ gọi hàm A khi ta click vào nút. Các bạn viết jQuery thường dùng cách ở dưới, nhưng không hiểu bản chất của việc mình đang làm.

3. Ứng dụng của callback

Như mình đã nói, Javascript là một ngôn ngữ khá thích hợp để giới thiệu callback. Ta có thể truyền thẳng 1 function vào 1 function khác, vì trong javascript 1 function được xem như 1 đối tượng (object). Trong các ngôn ngữ khác như C#, ta phải dùng delegate để truyền 1 function vào function khác (Nhớ kĩ câu này, mình sẽ nói rõ hơn ở bài sau).

Một số bạn sẽ hỏi: Callback mình code có xài mấy đâu? Thật ra trong quá trình code bạn có sử dụng callback mà không biết đấy (VD như code jQuery, hoặc gọi hàm khi user click vào 1 button trong WinForm, ASP.NET).

Callback có khá nhiều ứng dụng như sau:

  • Gọi 1 hàm khi có 1 số sự kiện xảy ra. VD như khi click vào 1 nút ta gọi hàm A, khi tắt cửa sổ ta gọi hàm B, v…v.
  • LINQ được xây dựng dựa trên khái niệm callback và lambda expression. Với callback, ta có thể thực hiện các thao tác như: Tìm 1 phần tử trong mảng, lọc phần tử trong mảng, sắp xếp mảng, … trở nên vô cùng đơn giản và thuận tiện. Các bạn có thể xem thêm tại bài viết Series C# hay ho: LINQ .
  • …..

5 phút quảng cáo cho bộ phim (series bài viết) sắp tới. Hẹn gặp lại các bạn.

pr-2

21 thoughts on “Callback trong javascript”

  1. E làm bên web, a ráng viết nhiều nhiều bài về javascript và jquery và lodash anh ơi. Cái cảm giác code chạy rồi mà k hiểu bản chất sau debug đuối đơ thiệt bực bội a ạ ^^

    Liked by 1 person

    1. Cảm ơn góp ý của bạn, trên blog mình cũng có viết 1 bài về lodash. Nắm vững khái niệm callback trong js, bạn sẽ hiểu rõ hơn cách vận hành của jQuery, lodash và các thư viện khác nhé 😀

      Liked by 1 person

  2. Em có thắc mắc xíu là:
    Trong function oNha tại sao mình lại phải truyền function tangQua để làm gì vậy?(vì truyền vào mới sinh ra chuyện delegate)
    Tại sao ở dưới mình không chỉ việc gọi nó và truyền tham số vào thôi mà phải truyền cả nó vào?

    Liked by 1 person

    1. Đôi khi ta muốn oNha chạy như bình thường, nhưng nó không gọi function tangQua mà tangBanh, tangGiay, v…v, lúc đó ra có thể truyền hàm tangBanh, tangGiay vào function oNha.
      Trong trường hợp javascript, có nhiều khi function oNha đã được thư viện viết sẵn, ta không thể mở code trong thư viện ra để gọi function tangQua của mình được. Thư viện cho phép ta truyền 1 function vào, rồi sẽ gọi như trong bài viết.

      Liked by 1 person

  3. mình không rành về javascript, đang học, cho mình thắc mắc tí.
    tại sao phải dùng callback function. ví dụ trên ta có thể viết lại như sau hoan toàn đc:

    function oNha() {
    var qua = “Quà đã nhận”;
    tangQua(qua);
    }

    vậy thì lợi ích của việc truyền tham số là function để làm gi?

    Liked by 1 person

    1. Tặng quà là một hành động cụ thể, vậy sẽ ra sao nếu người chồng không muốn tặng quà nữa mà yêu cầu đưa thư thì sao? Người chồng phải quay về nhà và nói với vợ thay đổi hành động.
      Đối với callback, ta có thể gọi function oNha() và truyền vào bất cứ function(hành động yêu cầu nào của người chồng) mà không cần tác động đến function oNha() ban đầu.

      Liked by 2 people

  4. Bản chất nhiều bạn đã code callback rất nhiều nhưng chắc là không để ý đó thôi.
    mục đích của callback là gọi tới 1 hàm(chức năng) nào đó mà ta muốn tại vị trí mình muốn. hay nói cách khác là truyền 1 hàm vào hàm khác để dùng thì gọi là callback. ví dụ của chủ thớt cũng dễ hiểu rồi nhỉ.
    Ví dụ: mình có 1 hàm common là
    sing = function(callback){
    // TODO: thực hiện chức năng của sing..

    // nếu có truyền hàm khác vào thì thực hiện hàm đó.
    if (callback && typeof callback === “function”) {
    callback();
    }
    }
    Giờ bạn muốn 1 ca sĩ thực hiện nhiệm vụ common là sing,
    ngoài ra còn muốn cô ấy nhảy nhót nữa. thì truyền action nhảy nhót vào để sing làm luôn.
    sing(dance=function(){
    // TODO: thực hiện điệu nhảy.
    });

    Nếu không muốn cô ấy dancing mà muốn cởi đồ thì add thêm $ cho cô ấy 🙂
    http://rao5s.vn

    Like

  5. trong nodejs có hàm đọc file như thế này:
    fs.readFileSync(‘path’, function(error, data){
    console.log(data); //data là file được đọc
    }
    bạn giải thích hộ mình cái gì truyền vào 2 parameter là error và data với. Với lại truyền như thế nào, ví dụ thì càng tốt ạ

    Like

    1. “cFunction” giống “url” là tên khai báo để dùng trong
      “function loadDoc(url, cFunction) {…}”
      MyFunction là đầu vào.

      “loadDoc(‘ajax_info.txt’, myFunction)” url = ‘ajax_info.txt’/ cFunction = myFunction.

      Like

  6. anh ơi giao diện web đang bị dạt về phía bên trái màn hình, nhìn hơi khó chịu ạ ^^

    Like

  7. Nếu đặt như này thì kq nó củng giống vậy. Mong ad giải thích.
    function oNha(vo) {
    var qua = “Quà đã nhận”;
    tangQua(qua);
    }

    Like

    1. vấn đề này được nhắc đến và giải đáp ít nhất 2 lần rồi , cậu quay lại cmt đọc lại sẽ hiểu

      Liked by 1 person

  8. Hình như chỗ jsfiddle đoạn code bị lộn chỗ showPopup, trong code phải như này đúng không ạ
    `
    var btn = document.getElementById(“btn”);
    var showPopup = function() { alert(“Hello from jQuery”); };

    $(‘#btn2’).click(showPopup);
    `

    Liked by 1 person

Leave a comment