Callback, Promise, Async Await
1. Event Loop
Javascript chạy đơn luồng, tương tự như ruby, nhưng khác một điều, môi trường làm việc của javascript đa phần là trình duyệt, nếu mọi thứ đều chạy tuần tự đơn luồng liệu có ổn không?
Ví dụ:
1 | API.get("/cats") |
Giả dụ đoạn code lấy về dữ liệu dogs bên trên gặp lỗi hoặc tốn rất nhiều thời gian để thực hiện, khi đó giao diện (trên trình duyệt) của người dùng sẽ treo hoàn toàn nếu javascript không có giải pháp cho sự đơn luồng và chạy tuần tự?
Cách giải quyết là nó đơn luồng và chạy không tuần tự, hay còn gọi là chạy bất đồng bộ:
Vậy javascript và ruby cùng là đơn luồng, nhưng javascript chạy bất đồng bộ còn ruby thì chạy đồng bộ tuần tự.
Video số [6] dưới mục tham khảo đã giải thích rất hay về event loop và không có lý do gì chúng ta đi ghi lại 1 thứ đã có người làm quá tốt. Một vài lưu ý mình lượm lặt nên note lại:
- Event Loop có một nhiệm vụ duy nhất - giám sát Call Stack và Callback Queue. Nếu Call Stack trống, nó sẽ lấy sự kiện đầu tiên từ queue và đẩy vào Call Stack
2.Những Web API này là gì? Chúng là những thread mà bạn không thể truy cập được, chỉ có thể gọi để xài mà thôi. Chúng là những nhân tố trong trình duyệt mà thực sự có thể chạy đồng thời (concurrency). Vậy thì event loop là gì:
- ES6 giới thiệu khái niệm về job queue được sử dụng bởi Promises trong JavaScript. Sự khác biệt giữa message queue và job queue là job queue có mức ưu tiên cao hơn message queue, có nghĩa là các promise job bên trong job queue sẽ được thực thi trước các callback bên trong message queue.
2. Callback
Trong js, function cũng là object.
Khi chúng ta truyền function A và function B dưới dạng tham số của B, lúc này A được gọi là Callback function.
1 | function A() { |
Khi chúng ta truyền function không tên vào B thay vì truyền 1 function có tên là A, lúc này function đó gọi là anonymous function, trường hợp này chúng ta làm rất nhiều, tiêu biểu là các event jquery chúng vẫn dùng hay hàm setTimeout build-in trong javascript cũng là một ví dụ tiêu biểu, nó nhận vào 2 tham số: một function và 1 khoảng thời gian dạng milisecond.
1 | function B(callback) { |
Tại sao cần dùng callback?
Vì bản chất của ngôn ngữ javascript là bất đồng bộ, làm gì làm luôn, mày làm trễ/chậm thì kệ mày, t** éo thích tuần tự.
1 | // Copy from: https://www.freecodecamp.org/news/what-is-a-callback-function-in-javascript/ |
Trong ví dụ trên, chúng ta giả lập 1 request tới server, và request này tốn 5s, sau khi request này có kết quả thì 1 function khác ở đây mới chạy, chính là function getResults, vì vậy truyền getResults dưới dạng callback function vào serverRequest rồi “sau khi nhận được response từ server” ta truyền dữ liệu đó cho callback function để nó làm công việc mà nó cần làm.
Một ví dụ khác:
1 | // Copy from: https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced |
Trong ví dụ trên, callback function sẽ chạy sau khi mà cái hàm T.get chạy xong, các tham số của callback function chính là các giá trị T.get trả về.
3. Promise
1 | let p = new Promise((resolve, reject) => { |
Ví dụ 2 về Promise.all
1 | let cats = new Promise((resolve, reject) => { |
4. Async Await
Clear code cho promise, được bổ sung trong ES7
1 | // Copy from: https://www.youtube.com/watch?v=V_Kr9OSfDeU |
Update thành dùng async await
1 | async function doWork() { |
5. References
[1]https://viblo.asia/p/javascript-callback-function-PdbGnozAeyA
[2]https://kipalog.com/posts/Promise-la-khi-gi-
[3]https://www.freecodecamp.org/news/what-is-a-callback-function-in-javascript/
[4]https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced
[5]https://viblo.asia/p/hieu-ve-asynchronous-javascript-RQqKLARmZ7z
[6]https://www.youtube.com/watch?v=8aGhZQkoFbQ
[7]https://www.youtube.com/watch?v=DHvZLI7Db8E
[8]https://www.youtube.com/watch?v=V_Kr9OSfDeU