Promise trong phong cách đồng bộ trong JavaScript
Để giải quyết vấn đề promise hell, một cú pháp đặc biệt cho promise đã được tạo ra, cho phép viết code bất đồng bộ dễ dàng hơn nhiều - theo phong cách đồng bộ.
Hãy bắt đầu nghiên cứu nó. Đầu tiên, lấy code từ bài học trước:
function func() {
getSmth(2).then(res => {
console.log(res); // sẽ in ra 4
});
}
func();
Nếu hàm getSmth của chúng ta là đồng bộ, thì code của hàm func chúng ta có thể viết lại như sau:
function func() {
let res = getSmth(2);
console.log(res); // sẽ in ra 4
}
Tuy nhiên, hàm getSmth là bất đồng bộ, vì vậy code trên sẽ không hoạt động. Nhưng, bằng cách sử dụng phong cách đồng bộ của promise, chúng ta có thể đạt được điều gì đó tương tự. Hãy làm điều đó.
Đầu tiên, chúng ta phải khai báo hàm func của mình là bất đồng bộ bằng lệnh đặc biệt async:
async function func() {
}
Sau đó, bên trong hàm func, chúng ta có thể sử dụng lệnh đặc biệt await. Lệnh này, được viết trước một promise, sẽ buộc JavaScript chờ cho đến khi promise được thực hiện xong. Sau đó, lệnh sẽ trả về kết quả của promise, và việc thực thi code sẽ tiếp tục.
Trong trường hợp của chúng ta, chúng ta phải viết await trước lời gọi getSmth. Vì kết quả của lời gọi hàm này sẽ là một promise, nên việc thực thi code tiếp theo sẽ chỉ tiếp tục sau khi promise này được thực hiện xong. Và, kết quả của promise có thể được gán vào một biến. Hãy thực hiện như đã mô tả:
async function func() {
let res = await getSmth(2);
console.log(res); // sẽ in ra 4
}
func();
Hãy gọi getSmth nhiều lần:
async function func() {
let res1 = await getSmth(2);
let res2 = await getSmth(3);
console.log(res1 + res2); // sẽ in ra 13
}
func();
Và bây giờ hãy gọi getSmth trong một vòng lặp:
async function func() {
let arr = [1, 2, 3, 4, 5];
let sum = 0;
for (let elem of arr) {
sum += await getSmth(elem);
}
console.log(sum);
}
func();
Viết lại code sau bằng cú pháp đồng bộ:
function func() {
getSmth(2).then(res1 => {
getSmth(3).then(res2 => {
getSmth(4).then(res3 => {
console.log(res1 + res2 + res3);
});
});
});
}
func();