Có ai giải thích tại sao thành công được ghi lại không?
Nói tóm lại: một .then
sau một .catch
trong một chuỗi Promise
sẽ luôn luôn được thực thi (trừ khi nó tự có lỗi).
Lời giải thích lý thuyết
Mã của bạn thực sự chỉ là một chuỗi Promise
đó là lần đầu tiên thực hiện đồng bộ cài đặt nó lên để hoàn thành không đồng bộ sau đó. Công cụ Javascript sẽ chuyển qua bất kỳ số reject()
hoặc Error
nào tới số .then
đầu tiên xuống chuỗi bằng một cuộc gọi lại reject
trong đó. Các từ chối gọi lại là chức năng thứ hai được truyền cho một .then
:
.then(
function(){
//handle success
},
function() {
//handle reject() and Error
})
Việc sử dụng .catch
là suger chỉ là cú pháp cho:
.then(null, function() {
//handle reject() or Error
})
Mỗi phòng trong số .then
's tự động trả về một mới Promise
có thể được hành động theo sau bởi .then
's (hoặc .catch
' s cũng là .then
's).
quán tưởng dòng chảy của chuỗi lời hứa của bạn
Bạn có thể hình dung dòng chảy của mã của bạn với ví dụ sau:
var step1 = new Promise (function (resolve, reject) {
setTimeout(reject('error in step1'), 1000);
})
var step2 = step1.then(null, function() {
// do some error handling
return 'done handling errors'
})
var step3 = step2.then(function() {
// do some other stuff after error handling
return 'done doing other stuff'
}, null)
setTimeout (function() {
console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);
console.log();
console.log ('Asynchronous code completed')
console.log();
}, 2000);
console.log ('step1: ', step1);
console.log ('step2: ', step2);
console.log ('step3: ', step3);
console.log();
console.log ('Synchronous code completed')
console.log();
mà khi chạy sẽ cho kết quả đầu ra sau trong giao diện điều khiển:
step1: Promise { <rejected> 'error in step1' }
step2: Promise { <pending> }
step3: Promise { <pending> }
Synchronous code completed
step1: Promise { <rejected> 'error in step1' }
step2: Promise { 'done handling errors' }
step3: Promise { 'done doing other stuff' }
Asynchronous code completed
'bắt' đóng vai trò giống như trong' try ... catch'. Nó bắt một sự từ chối, không chỉ chạm vào nó. Để đạt được hành vi mong đợi, bạn cần trả về một lời hứa bị từ chối từ 'catch' - hoặc tốt hơn, sử dụng một' then' duy nhất với lần gọi lại thứ hai. – estus
Bạn muốn 'promise.then (function() {console.log ('success');}, function() {console.log ('reject');}) 'để có được một hoặc không bao giờ cả hai. – Bergi
Xem thêm [tại sao .catch(). Catch() không chuyển tiếp ngoại lệ] (http://stackoverflow.com/questions/16371129/chained-promises-not-passing-on-rejection) – Bergi