TL; DR
Sử dụng Promise.all
cho các cuộc gọi chức năng song song, các hành vi trả lời không chính xác khi xảy ra lỗi.
Đầu tiên, thực hiện tất cả các cuộc gọi không đồng bộ cùng một lúc và có được tất cả các Promise
đối tượng. Thứ hai, sử dụng await
trên các Promise
đối tượng. Bằng cách này, trong khi bạn chờ người đầu tiên Promise
giải quyết các cuộc gọi không đồng bộ khác vẫn đang tiến triển. Nhìn chung, bạn sẽ chỉ chờ chừng nào cuộc gọi không đồng bộ chậm nhất. Ví dụ:
// Begin first call and store promise without waiting
const someResult = someCall();
// Begin second call and store promise without waiting
const anotherResult = anotherCall();
// Now we await for both results, whose async processes have already been started
const finalResult = [await someResult, await anotherResult];
// At this point all calls have been resolved
// Now when accessing someResult| anotherResult,
// you will have a value instead of a promise
Ví dụ về JSbin: http://jsbin.com/xerifanima/edit?js,console
Hãy cẩn thận: Sẽ không có vấn đề gì nếu các await
cuộc gọi nằm trên cùng một dòng hoặc trên các dòng khác nhau, miễn là await
cuộc gọi đầu tiên xảy ra sau tất cả các cuộc gọi không đồng bộ. Xem bình luận của JohnnyHK.
Cập nhật: câu trả lời này có thời gian xử lý lỗi khác nhau theo câu trả lời của @ bergi , nó KHÔNG loại bỏ lỗi khi xảy ra lỗi nhưng sau khi tất cả các lời hứa được thực hiện. Tôi so sánh kết quả với mẹo của @ jonny : [result1, result2] = Promise.all([async1(), async2()])
, kiểm tra đoạn mã sau
const correctAsync500ms = () => {
return new Promise(resolve => {
setTimeout(resolve, 500, 'correct500msResult');
});
};
const correctAsync100ms = () => {
return new Promise(resolve => {
setTimeout(resolve, 100, 'correct100msResult');
});
};
const rejectAsync100ms = () => {
return new Promise((resolve, reject) => {
setTimeout(reject, 100, 'reject100msError');
});
};
const asyncInArray = async (fun1, fun2) => {
const label = 'test async functions in array';
try {
console.time(label);
const p1 = fun1();
const p2 = fun2();
const result = [await p1, await p2];
console.timeEnd(label);
} catch (e) {
console.error('error is', e);
console.timeEnd(label);
}
};
const asyncInPromiseAll = async (fun1, fun2) => {
const label = 'test async functions with Promise.all';
try {
console.time(label);
let [value1, value2] = await Promise.all([fun1(), fun2()]);
console.timeEnd(label);
} catch (e) {
console.error('error is', e);
console.timeEnd(label);
}
};
(async () => {
console.group('async functions without error');
console.log('async functions without error: start')
await asyncInArray(correctAsync500ms, correctAsync100ms);
await asyncInPromiseAll(correctAsync500ms, correctAsync100ms);
console.groupEnd();
console.group('async functions with error');
console.log('async functions with error: start')
await asyncInArray(correctAsync500ms, rejectAsync100ms);
await asyncInPromiseAll(correctAsync500ms, rejectAsync100ms);
console.groupEnd();
})();