19 lượt xem

Async Await là gì? 6 lý do khiến Async Await trở nên vượt trội | Acb-win.com

Khi bạn chạy mã không đồng bộ trong JavaScript, thông thường bạn sẽ sử dụng lệnh gọi lại hoặc lời hứa. Tuy nhiên, vẫn có một cách để làm việc với mã không đồng bộ dễ dàng và hiệu quả hơn, đó là Async Await. Vậy Async Await là gì? Mã mẫu cho Async Await và lý do bạn nên sử dụng Async Await sẽ được Tino Group bật mí trong bài viết!

Chờ Async là gì?

JavaScript liên tục được cải tiến và trong bản cập nhật ES7 năm 2016, JavaScript đã được cập nhật thêm nhiều chức năng (chức năng) mới như: hàm mũi tên, phương thức mảng, vòng lặp for / in, ký tự mẫu, v.v.

Và trong đó có một chức năng mới giúp giải quyết vấn đề bất đồng bộ một cách nhanh chóng hơn, đó là chức năng Async Await.

Async Await được xây dựng trên cơ sở hàm Promise và tương thích với tất cả các API dựa trên Promise để xử lý các trường hợp không đồng bộ.

không đồng bộ-đợi-sau

Trong đó, chúng ta có Async Await với các tính năng sau:

  • Không đồng bộ được sử dụng để khai báo một hàm không đồng bộ và hàm sẽ luôn trả về một giá trị. Nếu lời hứa không được thực hiện, JavaScript sẽ tự động kết thúc quá trình.
  • Chờ đợi Được sử dụng để chờ các lời hứa trong một khối Async, cách sử dụng dễ hiểu của Await là “gọi” JavaScript để chờ một lời hứa được trả lại. Trong đó, await chỉ có công dụng triển khai hàm mà nó tạo ra không đồng bộ bằng cách đợi một khối trả về kết quả, await không đợi toàn bộ kết quả được trả về trong chương trình.

Cú pháp không đồng bộ

Đối với Async, bạn chỉ cần đặt từ Async ngay trước một hàm để hàm đó trả về một lời hứa. Ví dụ:

async function myFunction() {

 return "Hello";

}

Tương tự, đặt trước Lời hứa như sau:

async function myFunction() {

 return Promise.resolve("Hello");

}

So sánh với trường hợp bạn vừa sử dụng Hứalệnh của bạn sẽ trở thành như thế này:

myFunction().then(

 function(value) { /* code if successful */ },

 function(error) { /* code if some error */ }

);

Vui lòng đợi cú pháp

Cách sử dụng khá giống với Async, bạn chỉ cần nhập từ Await vào trước khi một hàm làm cho nó chờ Promise. Tuy nhiên, bạn chỉ có thể sử dụng Await trong khối trình quản lý Async!

let value = await Promise;

Ví dụ cơ bản khi sử dụng Await:

Chờ Async là gì?  6 lý do tại sao Async Await lại vượt trội hơn 3

QUẢNG CÁO

<!DOCTYPE html>

<html>

<body>

<h2>JavaScript Async / Await</h2>

<p>Đợi xíu! 3 giây thôi là bạn có thể nhìn thấy điều bất ngờ.</p>

<h1 ></h1>

<script>

async function myDisplay() {

 let myPromise = new Promise(function(myResolve, myReject) {

 setTimeout(function() { myResolve("Bạn đợi dòng này được 3S rồi đó!!"); }, 3000);

 });

 document.getElementById("demo").innerHTML = await myPromise;

}

myDisplay();

</script>

</body>

</html>

Đầu ra bạn sẽ nhận được như sau:

không đồng bộ-đợi-sau

Bạn có thể chỉnh sửa nội dung của mã và kiểm tra nó tại đây.

6 lý do tại sao bạn nên sử dụng Async Await

Mã trực quan, ngắn gọn và đơn giản

Tất nhiên, đây là một trong những ưu điểm lớn nhất của Async Await. Khi bạn viết mã, bạn sẽ không bị gián đoạn bởi những dòng mã phức tạp. Ví dụ, bạn chỉ cần thử / bắt để bắt lỗi chứ không bắt được lỗi, => đoạn mã của bạn sẽ trở nên chi tiết, cực kỳ phức tạp.

không đồng bộ-đợi-sau

Lỗi khi xử lý tăng tốc

Nếu bạn cảm thấy rằng try / catch vẫn không đủ để xử lý lỗi, chẳng hạn như mã try / catch sau:

const makeRequest = () => {

 try {

 getJSON()

 .then(result => {

 // this parse may fail

 const data = JSON.parse(result)

 console.log(data)

 })

 // bỏ ghi chú khối này để xử lý lỗi không đồng bộ bằng cách xóa dòng và xóa luôn các dấu //

 // .catch((err) => {

 // console.log(err)

 // })

 } catch (err) {

 console.log(err)

 }

Với mã Promise như thế này, try / catch sẽ không thể tìm và bắt lỗi nếu JSON.parse xảy ra trong Promise. Nếu muốn xử lý thì bạn sẽ phải gọi .catch bên trong và lặp lại đoạn mã một lần nữa để xử lý lỗi! Điều này thực sự phức tạp!

Bây giờ chúng ta sẽ giải quyết bằng cách sử dụng Async Await. Bạn có thể thấy rằng hàm catch có thể bắt lỗi cú pháp một cách hoàn hảo.

const makeRequest = async () => {

 try {

 // phân tích cú pháp này có thể không thành công

 const data = JSON.parse(await getJSON())

 console.log(data)

 } catch (err) {

 console.log(err)

 }

}

Đơn giản hóa câu điều kiện

Ví dụ: bạn muốn tải dữ liệu rồi xử lý và sau đó quyết định trả lại dữ liệu hoặc lấy thêm thông tin chi tiết dựa trên các giá trị đã nhập. Thông thường, chúng ta sẽ viết mã bằng cách lồng nhiều điều kiện như sau:

const makeRequest = () => {

 return getJSON()

 .then(data => {

 if (data.needsAnotherRequest) {

 return makeAnotherRequest(data)

 .then(moreData => {

 console.log(moreData)

 return moreData

 })

 } else {

 console.log(data)

 return data

 }

 })

}

Như bạn có thể thấy, đoạn mã có 6 điều kiện lồng nhau! Bạn chỉ cần đọc tất cả mọi thứ, bạn sẽ cảm thấy chóng mặt với mã này, đôi khi bạn sẽ bị rối và “bơi” trong mớ hỗn độn. Thay vì chấp nhận “mớ hỗn độn” của các kết hợp if / else, bạn có thể sử dụng Async Await để xử lý nó một cách đơn giản – dễ hiểu hơn theo cách này:

const makeRequest = async () => {

 const data = await getJSON()

 if (data.needsAnotherRequest) {

 const moreData = await makeAnotherRequest(data);

 console.log(moreData)

 return moreData

 } else {

 console.log(data)

 return data 

 }

}

Đơn giản hóa lời hứa trả hàng

Ví dụ, trong trường hợp bạn gọi 1 Promise1, hãy quay lại và gọi Promise2. Kết quả của họ đáp ứng các điều kiện và sẽ được gọi là Promise3. Mã của bạn sẽ trông như thế này:

const makeRequest = () => {

 return Promise1()

 .then(value1 => {

 // do something

 return Promise2(value1)

 .then(value2 => {

 // do something 

 return Promise3(value1, value2)

 })

 })

}

Trong trường hợp Promise3 không yêu cầu giá trị trả về là value1, thì mã sẽ đơn giản hơn một chút. Nếu một trường hợp khác với nhiều điều kiện hơn quay trở lại, mức độ làm tổ sâu hơn, bạn sẽ gặp rắc rối! Thay vì lồng ghép như vậy, bạn có thể sử dụng Promise.all để đơn giản hóa vấn đề (ví dụ Promise3 của bạn yêu cầu cả value1 và value2 đều được thỏa mãn).

const makeRequest = () => {

 return Promise1()

 .then(value1 => {

 // do something

 return Promise.all([value1, Promise2(value1)])

 })

 .then(([value1, value2]) => {

 // do something 

 return Promise3(value1, value2)

 })

}

Đơn giản hơn nữa, bạn có thể sử dụng Async Await để xử lý những việc sau:

const makeRequest = async () => {

 const value1 = await Promise1()

 const value2 = await Promise2(value1)

 return Promise3(value1, value2)

}

Thay vì một “đống” các hàm điều kiện, bây giờ bạn chỉ phải viết mã ít hơn và nếu người khác giúp bạn sửa mã, họ cũng dễ hiểu và giúp bạn tốt hơn.

Tạo ghi chú lỗi

Ví dụ: bạn có một đoạn mã sẽ gọi nhiều Lời hứa cùng một lúc trong một chuỗi và trong chuỗi có lỗi như trong mã này:

const makeRequest = () => {

 return callAPromise()

 .then(() => callAPromise())

 .then(() => callAPromise())

 .then(() => callAPromise())

 .then(() => callAPromise())

 .then(() => {

 throw new Error("oops");

 })

}

makeRequest()

 .catch(err => {

 console.log(err);

 // output

 // Error: oops at callAPromise.then.then.then.then.then (index.js:9:99)

Như bạn có thể thấy, nhật ký lỗi của bạn chỉ trả về số hàng và hàm cụ thể bị lỗi. Chỉ một hàng được trả lại:

// Error: oops at callAPromise.then.then.then.then.then (index.js:9:99)

Nếu sử dụng Async Await, nội dung sẽ được trả về hàm nơi xảy ra lỗi, ví dụ trực quan như sau:

const makeRequest = async () => {

 await callAPromise()

 await callAPromise()

 await callAPromise()

 await callAPromise()

 await callAPromise()

 throw new Error("oops");

}

makeRequest()

 .catch(err => {

 console.log(err);

 // output

 // Error: oops at makeRequest (index.js:7:9)

 })

Khi bạn được cung cấp địa chỉ nhà và bạn cũng biết chủ sở hữu, việc sửa chữa sai lầm trở nên dễ dàng hơn nhiều. Như bạn có thể thấy ở đây, đưa ra một yêu cầu và dẫn chúng ta đến lý do 6: giải pháp đơn giản và dễ dàng.

Gỡ lỗi đơn giản và dễ dàng hơn

Không có nỗi đau nào lớn hơn việc sửa mã! Và việc sử dụng Async Await giúp việc gỡ lỗi trở nên dễ dàng hơn rất nhiều! Với Async Await, bạn chỉ cần gỡ lỗi từng dòng như bình thường và bạn không phải gọi lặp đi lặp lại các hàm mũi tên khiến mọi thứ phức tạp.

không đồng bộ-đợi-sau

Qua bài viết, bạn có thể thấy rằng Async Await đã giúp cho code của bạn trở nên trực quan, ngắn gọn và dễ hiểu hơn bao giờ hết. Tino Group hy vọng những ví dụ này có thể giúp bạn quản lý mã của mình một cách đẹp mắt và có trật tự hơn!

Bài viết có tham khảo nội dung của: Hackernoon, Developer Mozilla và W3School.

Câu hỏi thường gặp

Hàm gọi lại là gì?

Mô tả một cách đơn giản, Callback là hành động chuyển đoạn mã A vào một đoạn mã B và tại một thời điểm nhất định, một sự kiện, đoạn mã A có thể thực hiện cuộc gọi đến đoạn mã B để xử lý một sự kiện không đồng bộ.

Liệu những lời hứa có trở nên lỗi thời?

Không, vẫn có nhiều trường hợp không sửa được Async Await và bạn vẫn cần sử dụng Promise để xử lý.

Ngoài ra, bạn cũng nên tìm hiểu thêm về Promise để hiểu cơ bản hơn và sử dụng Async Await “nhuần nhuyễn” hơn.

Async Await được hỗ trợ trên những phiên bản trình duyệt nào?

Ngoại trừ phiên bản Internet Explorer 7.0 trở về trước sẽ không được hỗ trợ, hầu hết các phiên bản trình duyệt khác đều được hỗ trợ.

Tìm hiểu thêm về Async Await ở đâu?

Bạn có thể học tại W3School hoàn toàn miễn phí tại đây. Không chỉ học Async Await, bạn còn được học JS, SQL, Python, PHP, Java, … và nhiều ngôn ngữ khác hoàn toàn miễn phí!

CÔNG TY TNHH TẬP ĐOÀN TINO

  • Trụ sở chính: L17-11, Lầu 17, Tòa nhà Vincom Center, Số 72 Lê Thánh Tôn, P. Bến Nghé, Q.1, TP.
    VPĐD: 42 Trần Phú, P.4, Q.5, TP.HCM
  • Điện thoại: 0364 333 333
    Tổng đài miễn phí: 1800 6734
  • Email: sales@tino.org
  • Trang web: www.tino.org

READ  SOLID là gì? 5 nguyên tắc của SOLID | Acb-win.com