Xử lý bất đồng bộ trong Javascript

Xử lý bất đồng bộ trong Javascript

Javascript là ngôn ngữ hoạt động theo cơ chế đơn luồng và đồng bộ. Nghĩa là chỉ một đoạn mã có thể được thực thi tại một thời điểm và nó sẽ thực hiện tuần tự. Tuy nhiên, có một số tác vụ như Call API, timeout, đọc tệp... thì Javascript xử lý bất đồng bộ. Chính vì vậy ta cần xử lý bất đồng bộ.

Ví dụ về trường hợp bất đồng bộ trong javascript:

setTimeout(()=>{
console.log(1);
},2000)
setTimeout(()=>{
console.log(2);
},1000)
setTimeout(()=>{
console.log(3);
},200)
setTimeout(()=>{
console.log(4);
},500)
setTimeout(()=>{
console.log(5);
},100)
// Output:
5
3
4
2
1

Các cơ chế để xử lý bất đồng bộ

Sử dụng hàm callback để xử lý bất đồng bộ

Một hàm sẽ được truyền vào một hàm khác và sẽ được gọi sau khi tác vụ bất đồng bộ hoàn tất.

Ví dụ với trường hợp timeout bên trên. Có thể sử dụng callback như sau:

setTimeout(()=>{
console.log(1);
setTimeout(()=>{
console.log(2);
setTimeout(()=>{
console.log(3);
setTimeout(()=>{
console.log(4);
setTimeout(()=>{
console.log(5);
},100)
},500)
},200)
},1000)
},2000)
// Output
1
2
3
4
5

Tuy nhiên, nếu có nhiều callback lồng nhau, sẽ dễ dẫn đến vấn đề gọi là "callback hell" làm cho code khó đọc và bảo trì.

Sử dụng Promise để xử lý bất đồng bộ

Promise javascript ra đời từ ES6 (ECMAScript 2015) và nó là một đối tượng đại diện cho một giá trị chưa biết tại thời điểm hiện tại, nhưng sẽ được hoàn thành hoặc bị từ chối trong tương lai. Promise có hai trạng thái chính: resolve (hoàn thành) hoặc reject (thất bại).

Cú pháp để tạo promise

const promise = new Promise((resolve,reject)=>{
//todo
sử dụng resolve(value) nếu không gặp vấn đề gì (hoàn thành)
sử dụng reject() nếu lỗi
})

Tương ứng với resolve và reject chúng ta sẽ sử dụng then hoặc catch để xử lý promise

  1. sử dụng then nếu promise resolve
  2. sử dụng catch để bắt lỗi nếu promise reject
promise.then(data =>console.log(data))
.catch(error =>console.error(error));

Về cơ bản thì chúng ta sẽ sử dụng những promise hơn là tạo ra chúng, nhưng điều quan trọng vẫn là bạn phải biết cách tạo ra chúng.

Ví dụ:

// Call API: https://dummyjson.com/products
const data = fetch('https://dummyjson.com/products')
console.log(data); // là 1 promise
data.then(value=>{
  console.log(value); // Trả về response => cần chuyển json
  const product = value.json()
  console.log(product); // là 1 promise
  product.then(value=>{
    console.log(value);    
  })
})

Sử dụng hàm bất đồng bộ Async/Await để xử lý bất đồng bộ

Async/await ra đời từ ES7(ECMAScript 2016) , async/await hiểu đơn giản là nó sẽ xử lý các promise. Nghĩa là thay vì chúng ta sử dụng then,catch để lấy dữ liệu và bắt lỗi thì chúng ta sử dụng async/await để làm điều đó.

Cú pháp : Như hàm thông thường nhưng thêm async vào trước function hoặc async vào trước dấu khai báo tham số của hàm arrow function và thêm await vào trước 1 promise

Ví dụ:

async function getProduct(){
  try {
  const data = await fetch('https://dummyjson.com/products')
  console.log(data); // Trả về response => cần chuyển json
  const product = await data.json()
  console.log(product); 
  } catch (error) {
  console.log(error);  
  }  
}
getProduct()

Đối với Arrow function

const getProduct = async ()=>{
  try {
  const data = await fetch('https://dummyjson.com/products')
  console.log(data); // Trả về response => cần chuyển json
  const product = await data.json()
  console.log(product); 
  } catch (error) {
  console.log(error);  
  }  
}
getProduct()



Được viết bởi: Ngọc Ngô

Bài viết cùng chuyên mục

Vote 0