Callbacks, Promises, and Async/Await trong Javascript

## Callback Function

Điểm khác biệt lớn của Javascript so với những ngôn ngữ khác là kỹ thuật dành cho xử lý không đồng bộ (Asynchronous). Trong một đoạn code, các lệnh sẽ thực hiện step by step, từng dòng lệnh. Giả sử có một dòng lệnh đọc xuống file, đòi hỏi xử lý I/O. Đối với ngôn ngữ như Java / C#, đoạn code sẽ dừng ở đây, chờ đọc file xong, rồi đi tiếp. Đối với Javascript, nó sẽ có một cách khác. Thay vì phải chờ đọc files xong, những dòng lệnh tiếp theo sẽ tiếp tục chạy. Và việc đọc file sẽ được trả về sau. Khi đó mình define một method gọi là Callback. Nói với nó là khi nào mày đọc file xong, thì gọi cại method callback này cho tao.

function readFile(fileName, callback) {
  // Read file
  // Handle error 
  // Return the error and data with callback if any.
  callback(fullName);
}

function callback(error, data) {
// Do something late.
}
readFile('path', callback);

## Callback hell

function readFile(fileName, callback) {
  // Read file
  callback(fullName);
}

function updateDataBaseInfo(info, callback) {
   // Update database
}

function sendEmail(info, callback) {
   // Send email
}

readFile('path', function {error, data} {
   updateDataBaseInfo(data, function(error, data) {
      sendEmail(data, function(error, data) {
         // If no error, All done!
         // If error, revert everything.
      })
   })
});

Trong ví dụ trên có 3 việc mình phải làm một cách lần lượt. Nếu chỉ sử dụng callback, mình sẽ bị lồng rất là nhiều function vào trong function. Điều này sẽ làm code chúng ta rất khó đọc, lâu dài sẽ khó refactor, maintain. Nhiều cái callback lồng nhau như vậy, mình gọi là vấn đề callback hell.

Ví dụ ở trên, các bạn có thể mỗi các function ban đầu giờ mình trả về một đối tượng Promise.
– Resolve: Nó trả lời cho lời hứa của nó, bằng một kết quả data.
– Reject: Có gì sai sót xảy ra, mình trả về lỗi để bên ngoài xử lý. Bên ngoài nếu muốn xử lý thì sử dụng method ‘error’ của đối tương Promise.
– Trường hợp không sử dụng, không gọi 2 method này: Tức là mày hứa mà mình im im không trả lời gì hết. Xong rồi hay lỗi cũng không báo.

## Promise
Hứa thật nhiều thất hứa thì cũng thật nhiều ^^
Thay vì phải Callback nhiều cấp, thì Javascript bây giờ sinh ra một đối tượng Promise, để hứa hẹn với mình. Mình chỉ cần dựa trên thằng này để xử lý tiếp theo.

function readFile(fileName) {
  return new Promise(resolve, reject) {
     // reject(error)
     // resolve(data)
  }
}

function updateDataBaseInfo(info) {
  return new Promise(resolve, reject) {
     // resolve or reject
  }
}

function sendEmail(info, callback) {
  return new Promise(resolve, reject) {
     // resolve or reject
  }
}

var promiseForReaddingFile = readFile();
promiseForReaddingFile
.then(function() {
    return updateDataBaseInfo()
})
.then(function() {
    return sendEmail()
})
.then(function() {
    // All done
})
.error(function() {
    // Something wrong happen
})

Theo như ví dụ ban đầu các bạn sẽ thấy cái Callback hell nó đã giải quyết. Code của chúng ta đẹp đẽ, sáng sủa hơn.

## Async/Await
Promise 
thực sự cả giải quyết vấn đề của Callback hell khá là tốt. Tuy nhiên, code lúc này vẫn chưa phải là tuyệt đẹp. Nên Javascript sinh ra môt thằng mới là Async/Await. Đoạn code bên trên sẽ được viết lại như sau khi sử dụng Async/Await

function readFile(fileName) {
  return new Promise(resolve, reject) {
     // reject(error)
     // resolve(data)
  }
}

function updateDataBaseInfo(info) {
  return new Promise(resolve, reject) {
     // resolve or reject
  }
}

async function sendEmail(info) {
   // Do somthing 
}

var responseAfterReadingFile = await readFile();
var responseAfterUpdatingDatabase = await updateDataBaseInfo()
var responseAfterSendingEmail = await sendEmail()

Trong ví dụ trên, chúng ta hay keyword mới được sử dụng Async và Await
– Async dùng để định nghĩa một method dưới dạng Promise. Tức là method này có sự defer (trả về cái gì đó một cách bất đồng bộ).
– Await dùng để chờ một method Async thực hiện xong, trả về kết quả. Await cũng có wait trên một đối tượng Promise như trong ví dụ trước.
+ readFile, updateDataBaseInfo vẫn trả về Promise
+ sendEmail sử dụng Async để định nghĩa method.

Nguồn tham khảo:
https://scotch.io/courses/10-need-to-know-javascript-concepts/callbacks-promises-and-async

Leave A Reply

Your email address will not be published. Required fields are marked *