[Back To Basic] Callback trong Javascript

MỞ ĐẦU

Khi bắt đầu làm việc hay tìm hiểu về Javascript, ta thường bắt gặp khái niệm gọi là callbacks. Bản thân mình khi mới bắt đầu làm việc vs Js cũng thấy khá là khó hiểu và chỉ sử dụng mà không hiểu bản chất. Tuy nhiên đây là khái niệm khá là quan trọng và cần nắm rõ cách thức hoạt động để khai thác tối đa sức mạnh của ngôn ngữ. Trong bài viết này, mình sẽ quay ngược lại từ những thứ cơ bản nhất, thông qua những ví dụ đơn giản, dễ hiểu để cùng làm rõ khái niệm callback trong Javascript.

Callback là gì

HIểu theo cách đơn giản: Callback là một function, được thực thi sau khi một function khác thực thi xong (thường là bất đồng bộ), nên nó có tên là call back (gọi lại)

Phức tạp hơn: Trong Javascript, functions là objects, bởi vậy, một function có thể nhận tham số là function, và cũng có thể trả về một function. Bất cứ function nào được truyền vào như một tham số và được gọi sau đó được gọi callback function.

Tại sao lại cần callbacks

Bởi một lý do rất quan trọng đó là Javascript là ngôn ngữ hướng sự kiện (event driven), thay vì chờ response, Javascript sẽ vẫn tiếp tục thực thi các câu lệnh khác, đồng thời vẫn lắng nghe response từ các event. Cùng xét ví dụ sau:

function first(){
  console.log(1);
}

function second(){
  console.log(2);
}

first();
second();

Đoạn code trên đơn giản là in ra kết qua ra màn hình console của trình duyệt

// 1
// 2

Nhưng sẽ thế nào nếu function first() chứa đoạn code mà không thể thực thi ngay tại thời điểm được gọi, ví dụ như function first() phải thực hiện API call và mất một khoảng thời gian mới nhận được response trả về ? Để mô phỏng hành động này, ở đây mình sẽ sử dụng setTimeout và để delay 500ms. Đoạn code mới sẽ trông như sau:

function first(){
  // Simulate a code delay
  setTimeout( function(){
    console.log(1);
  }, 500 );
}

function second(){
  console.log(2);
}

first();
second();

Lúc này thứ tự thực hiện các function vẫn như cũ nhưng kết quả đã khác:

// 2
// 1

Không phải là Javascript không thực hiện theo thứ tự mà ta mong muốn, mà là Javascript sẽ không đợi function first() thực hiện xong rồi mà thực hiện function second(). Để đảm bảo Js thực hiện đúng thứ tự ta định sẵn, cũng chính là lý do mà ta cần sử dụng đến khái niệm callback function.

Tạo một callback

Đầu tiên khai báo một function, với tham số là công việc cần giải quyết:

function startWork(work) {
  console.log(`Start to ${work}`);
}

startWork('wash clothes');
// Start to wask closthes

Add thêm callback như là một tham số của function startWork():

function startWork(work, callback) {
  console.log(`Start to ${work}`);
  callback();
}

startWork('wash clothes'', function() {
  console.log('Finish working!');
});
// Start to wask closthes
// Finish working

Như kết quả bên trên, đoạn text Finish working! được đảm bảo sẽ chỉ được in ra sau khi đoạn text Start to wask closthes đươc in - đúng theo thứ tự ta mong muốn. Ngoài ra callback không nhất thiết luôn phải định nghĩa bên trong lời gọi hàm:

function startWork(work, callback) {
  console.log(`Start to ${work}`);
  callback();
}

function finishWork() {
   console.log('Finish working!');
}

startWork('wash clothes'', finishWork);

Kết quả là tương tự nhau, tuy nhiên, function finishWork() có thể được tái sử dụng lại sau đấy.

Ví dụ trong thực tế

Trong dự án mà mình đang làm có yêu cầu đồng bộ với các sự kiện trên google calendar, vì vậy app sẽ cần get dữ liệu từ Google Calendar API, 1 request điển hình có thể hình dung ra như sau:

EventsAPI.get('search/events', params, function(err, data, response) {
  if(!err){
    // Thao tác với data response ở đây
  } else {
    console.log(err);
  }
});

Ở đây, EventsAPI.get đơn giản là thực hiện 1 HTTP GET request tới Google API, function này nhận 3 tham số: đường dẫn tới API, các params mà API yêu cầu và 1 anonymous function đóng vai trò là callback. Callback quan trọng ở đây là vì khi thực hiện API request, ta không chắc rằng có response trả về hay không, vì vậy callback ở đây đảm bảo rằng chỉ khi request thành công, ta mới thực hiện các công việc tiếp theo.

TỔNG KẾT

Trên đây là kiến thức cơ bản về callback mà chắc chắn những người làm việc với Js gặp phải. Hi vọng bài viết giúp ích được phần nào cho những người mới làm quen với Js.

Nguồn tham khảo

  1. Sitepoint