Những điều quan trọng cần hiểu ở đây
Cả hai thenvà các catchhàm trả về các đối tượng lời hứa mới.
Hoặc ném hoặc từ chối rõ ràng, sẽ chuyển lời hứa hiện tại sang trạng thái bị từ chối.
Kể từ khi thenvà catchtrả lại các đối tượng lời hứa mới, chúng có thể bị xiềng xích.
Nếu bạn ném hoặc từ chối bên trong một trình xử lý lời hứa ( thenhoặc catch), nó sẽ được xử lý trong trình xử lý từ chối tiếp theo xuống đường dẫn chuỗi.
Như jfriend00 đã đề cập, trình xử lý thenvà catchtrình xử lý không được thực thi đồng bộ. Khi một người xử lý ném, nó sẽ kết thúc ngay lập tức. Vì vậy, ngăn xếp sẽ được mở ra và ngoại lệ sẽ bị mất. Đó là lý do tại sao ném một ngoại lệ từ chối lời hứa hiện tại.
Trong trường hợp của bạn, bạn đang từ chối bên trong do1bằng cách ném một Errorvật thể. Bây giờ, lời hứa hiện tại sẽ ở trạng thái bị từ chối và quyền kiểm soát sẽ được chuyển sang xử lý tiếp theo, đó là thentrong trường hợp của chúng tôi.
Vì thentrình xử lý không có trình xử lý từ chối, nên do2sẽ không được thực thi. Bạn có thể xác nhận điều này bằng cách sử dụng console.logbên trong nó. Vì lời hứa hiện tại không có trình xử lý từ chối, nên nó cũng sẽ bị từ chối với giá trị từ chối từ lời hứa trước đó và quyền kiểm soát sẽ được chuyển sang trình xử lý tiếp theo catch.
Như catchlà một trình xử lý từ chối, khi bạn thực hiện console.log(err.stack);bên trong nó, bạn có thể thấy dấu vết ngăn xếp lỗi. Bây giờ, bạn đang ném một Errorđối tượng từ nó để lời hứa được trả lại catchcũng sẽ ở trạng thái bị từ chối.
Vì bạn chưa đính kèm bất kỳ trình xử lý từ chối nào vào catch, nên bạn không thể quan sát từ chối.
Bạn có thể chia chuỗi và hiểu điều này tốt hơn, như thế này
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
Đầu ra bạn sẽ nhận được sẽ giống như
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
Trong catchtrình xử lý 1, bạn sẽ nhận được giá trị của promiseđối tượng là bị từ chối.
Tương tự, lời hứa được trả về bởi catchtrình xử lý 1, cũng bị từ chối với cùng một lỗi promisebị từ chối và chúng tôi đang quan sát nó trong catchtrình xử lý thứ hai .
.catch(…)trở về.