3.1 Tạo chuỗi promises
Chuỗi promises cho phép thực hiện tuần tự nhiều thao tác bất đồng bộ, chuyển kết quả của một thao tác vào thao tác tiếp theo. Điều này làm cho code dễ đọc hơn và dễ quản lý hơn. Ngoài ra, promises cung cấp khả năng mạnh mẽ để xử lý lỗi, giúp tạo ra ứng dụng ổn định và bền bỉ.
Khái niệm cơ bản
Chuỗi promises được tạo bằng cách trả về một promise mới từ phương thức then
. Mỗi phương thức then
trả về một promise mới, cho phép tạo ra các thao tác bất đồng bộ tuần tự.
Ví dụ về chuỗi promises đơn giản
Trong ví dụ này, mỗi phương thức then
thực hiện thao tác của riêng nó và chuyển kết quả cho phương thức then
tiếp theo.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Step 1 completed');
}, 1000);
});
promise
.then((result) => {
console.log(result); // Sẽ hiện: Step 1 completed
return 'Step 2 completed';
})
.then((result) => {
console.log(result); // Sẽ hiện: Step 2 completed
return 'Step 3 completed';
})
.then((result) => {
console.log(result); // Sẽ hiện: Step 3 completed
})
.catch((error) => {
console.error(error);
});
Ví dụ chuỗi với các thao tác bất đồng bộ
Trong ví dụ này, mỗi phương thức then
chờ đợi hoàn thành thao tác bất đồng bộ trước khi thực hiện bước tiếp theo:
function asyncOperation(step) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${step} completed`);
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result); // Sẽ hiện: Step 1 completed
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result); // Sẽ hiện: Step 2 completed
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Sẽ hiện: Step 3 completed
})
.catch((error) => {
console.error(error);
});
3.2 Xử lý lỗi trong chuỗi promises
Phương thức catch
được sử dụng để xử lý lỗi trong chuỗi promises. Nếu có lỗi xảy ra trong bất kỳ promise nào, nó sẽ được chuyển tới phương thức catch
gần nhất. Điều này cho phép xử lý lỗi tập trung, cải thiện khả năng đọc và bảo trì code.
Ví dụ về xử lý lỗi
Trong ví dụ này, lỗi xảy ra ở Step 2
, được bắt bởi phương thức catch
, và các phương thức then
sau đó không thực hiện:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true); // Thao tác này sẽ kết thúc với lỗi
})
.then((result) => {
console.log(result); // Đoạn code này sẽ không thực hiện
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Đoạn code này sẽ không thực hiện
})
.catch((error) => {
console.error('Error:', error); // Sẽ hiện: Error: Step 2 failed
});
Xử lý lỗi trong các bước cụ thể
Đôi khi cần xử lý lỗi trong các bước cụ thể của chuỗi mà không làm gián đoạn thực hiện toàn bộ chuỗi. Để làm điều này có thể sử dụng các phương thức then
và catch
lồng nhau.
Ví dụ xử lý lỗi trong các bước cụ thể
Trong ví dụ này, lỗi trong Step 2
được xử lý cục bộ, và chuỗi tiếp tục thực hiện với giá trị đã phục hồi:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true).catch((error) => {
console.warn('Handled error in Step 2:', error);
return 'Recovered from Step 2 error';
});
})
.then((result) => {
console.log(result); // Sẽ hiện: Recovered from Step 2 error
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Sẽ hiện: Step 3 completed
})
.catch((error) => {
console.error('Error:', error); // Đoạn code này sẽ không thực hiện
});
3.3 Sử dụng finally
Phương thức finally
được sử dụng để thực hiện code bất kể promise hoàn thành thành công hay lỗi. Điều này hữu ích cho việc thực hiện các hành động kết thúc, chẳng hạn như dọn dẹp tài nguyên.
Ví dụ sử dụng finally:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result);
return asyncOperation('Step 3');
})
.catch((error) => {
console.error('Error:', error);
})
.finally(() => {
console.log('All operations completed'); // Sẽ thực hiện trong mọi trường hợp
});
Trong ví dụ này, phương thức finally
luôn được thực hiện, bất kể có lỗi xảy ra hay không.
GO TO FULL VERSION