Async/Await là gì? | How Kteam

Dẫn nhập

Trong bài viết hôm nay, Kteam sẽ giới thiệu cho các bạn một tính năng Async/Await trong ES7

Nội dung

Để theo dõi bài này tốt nhất, bạn nên xem qua bài:

  • Sổ tay Javascript
  • ECMAScript là gì?
  • Node.js là gì?
  • Cơ chế bất đồng bộ trong Javascript
  • Node.js hoạt động như thế nào?
  • Promise là gì?

Bài này sẽ giới thiệu những nội dung sau:

  • Async/Await là gì?
  • Async/Await và Promise
  • Cách sử dụng Async/Await hiệu quả

Async/Await là gì?

Async/Await là một tính năng ra đời từ ES7 nhằm giúp ta code bất đồng bộ nhìn trong đồng bộ hơn, giúp code dễ nhìn hơn và dễ sử dụng. Trong đó:

  • Async function là một khái niệm định nghĩa cho hàm bất đồng bộ. Hàm bất đồng bộ này sẽ thực hiện tách rời so với phần code còn lại của Event Loop, và trả về một Promise. Cú pháp và cấu trúc của
    Async function làm nhìn giống chuẩn các hàm đồng bộ.
  • Await là một cú pháp giúp tạm dừng (block) code để đợi lấy kết quả từ một Promise (Await không hoạt động với callback), và
    Await chỉ sử dụng được khi nằm trong Async function.

Ví dụ: Ta sẽ viết 1 function dùng Async/Await để xử lý 1 Promise

  • Khai báo function returnPromise khi gọi sẽ return 1 promise, sau 3 giây thì promise sẽ resolve kết quả.
  • Khai báo function asyncFunction dùng tính năng async/await, khi gọi function
    returnPromise  sẽ dùng await để đợi kết quả.

Ta sẽ xem kết quả của nó:

Như vậy:

  • Khi gọi asyncFunction đầu tiên thì chương trình sẽ log ‘calling’, nhưng khi chương trình await nên chương trình thực hiện log ‘kteam’ tiếp theo.
  • Sau 3 giây thì returnPromise có kết quả, lúc đó asyncFunction thực hiện tiếp phần code còn lại.

function returnPromise() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve('finished')
      }, 3000)
    })
}

async function asyncFunction() {
  console.log('calling')
  var result = await returnPromise()
  console.log(result)
}

asyncFunction()
console.log('kteam')

Async/Await và Promise

Nếu chúng ta xem qua, sẽ nghĩ rằng khi sử dụng Async/Await thì không cần phải sử dụng Promise nửa. Cũng không hẳn là vậy, vì bản chất khi ta sử dụng Async/Await chính là ta sử dụng gián tiếp Promise, khi async function return thì
nó sẽ trả về 1 Promise, nếu ta hiểu bản chất sẽ biết cách áp dụng triệt để:


function returnPromise() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve(5)
      }, 3000)
    })
}

async function asyncFunction() {
  var result = await returnPromise()
  return result + 5
}

var promise = asyncFunction()

promise.then(function (value) {
  console.log(value)
})

Ngoài ra: Chỉ có Promise có thể xử lý các trường hợp Callback ở các thư viện cũ, nên có lúc ta phải tự viết Promise để xử lý vấn đề cũ này.

Cách sử dụng Async/Await hiệu quả

Khi sử dụng Async/Await nó giúp chúng ta nhìn code tường minh hơn vì giúp code trở lại đồng bộ, tuy nhiên nếu quá lạm dụng thì sẽ làm chậm code.

Ví dụ:


function returnResultAfter3Seconds() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve(5)
      }, 3000)
    })
}
  
function returnResultAfter5Seconds() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve(5)
      }, 5000)
    })
}

async function asyncFunction() {
  var result1 = await returnResultAfter3Seconds()
  var result2 = await returnResultAfter5Seconds()
  return result1 + result2
}

var promise = asyncFunction()

promise.then(function (value) {
  console.log(value)
})

Trong trường hợp này, ta có 2 hàm bất đồng bộ lần lượt mất 3 và 5 giây mới có kết quả, vì
asyncFunction sử dụng await lần lượt thì mất đến 8 giây mới có thực hiện xong. Đây là vấn đề khi quá lạm dụng Async/Await khi không hiểu bản chất rõ Javascript, vì sức mạnh của ngôn ngữ Javascript chính là bất đồng bộ, khi ta viết như thế này
sẽ không phát huy được tính năng của nó.

Để khắc phục tình trạng này, sử dụng Promise.all để cho 2 function chạy cùng 1 lúc, lúc đó thời gian giảm xuống còn 5 giây


function returnResultAfter3Seconds() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve(5)
      }, 3000)
    })
}
  
function returnResultAfter5Seconds() {
    return new Promise(function(resolve,reject) {
      setTimeout(function() {
        resolve(5)
      }, 5000)
    })
}

async function asyncFunction() {
  var array = await Promise.all([returnResultAfter3Seconds(), returnResultAfter5Seconds()])
  var result = 0
  for (var i = 0; i < array.length - 1; i++) {
    result += array[i]
  }
  return result
}

var promise = asyncFunction()

promise.then(function (value) {
  console.log(value)
})

Kết

Như vậy Kteam đã giới thiệu về Async/Await

Ở bài tiếp theo, Kteam sẽ giới thiệu cho các bạn
Var, Let và Const

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.

Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.