2013-10-30 21 views
6

Re: https://github.com/tildeio/rsvp.jsLàm thế nào rsvp.js xử lý từ chối lời hứa với chuỗi của thất bại callbacks

Tôi có một chức năng gọi doSomething() mà làm điều gì đó cho một thời gian ngắn và sau đó trả về một RSVP.Promise. Sau đó, một chuỗi các cuộc gọi lại thành công và thất bại là được đăng ký với lời hứa trả lại (xem mã bên dưới). Hành vi mà tôi mong đợi là, nếu lời hứa được thực hiện, chuỗi cuộc gọi thành công đã đăng ký với lời hứa sẽ bị hủy và nếu lời hứa bị từ chối (không thành công), chuỗi lỗi gọi lại sẽ bị hủy.

Tôi nhận được hành vi mong đợi khi lời hứa được hoàn thành, nhưng tôi nhận được hành vi khác với những gì tôi mong đợi khi lời hứa bị từ chối. Tức là, các cuộc gọi lại thành công bị chặn và đầu ra của một cuộc gọi lại thành công được chuyển đến cuộc gọi lại thành công tiếp theo trong chuỗi. Nhưng nó xuất hiện các callbacks thất bại không bị xích. Chúng hoạt động gần giống như phần bắt giữ trong khối thử/nắm bắt (xem mã và đầu ra bên dưới).

Ai đó có thể giải thích hành vi này? Đây có phải là cách nó giả sử để làm việc hay là lỗi này trong cách rsvp.js xử lý một lời hứa bị từ chối/thất bại mà có một chuỗi các cuộc gọi lại không được đăng ký với nó? Tôi đang đọc Promises/A + spec bây giờ để thử và tìm ra điều này, nhưng nếu ai đó biết công cụ này ra khỏi đỉnh đầu của họ, rất thích nghe lời giải thích của bạn. Cảm ơn trước.

jsfiddle: http://jsfiddle.net/rylie/VYSj7/2/

doSomething() // returns an RSVP.Promise object 
    .then(
     function(message) { console.log("then success 1: " + message); return "from success 1"; }, // success callback 
     function(message) { console.log("then failure 1: " + message); return "from failure 1"; } // failure callback 
    ) 
    .then(
     function(message) { console.log("then success 2: " + message); return "from success 2"; }, // success callback 
     function(message) { console.log("then failure 2: " + message); return "from failure 2"; } // failure callback 
    ) 
    .then(
     function(message) { console.log("then success 3: " + message); return "from success 3"; } // success callback 
    ) 
    .then(
     null, 
     function(message) { console.log("then failure 4: " + message); return "from failure 4"; } // failure callback 
    ) 
    .then(
     function(message) { console.log("then success 5: " + message); return "from success 5"; }, // success callback 
     function(message) { console.log("then failure 5: " + message); return "from failure 5"; } // failure callback 
    ); 

** Khi lời hứa được hoàn thành (thành công), điều này được đầu ra tôi nhận được và mong đợi:

then success 1: Promise fulfilled! 
then success 2: from success 1 
then success 3: from success 2 
then success 5: from success 3 

** Khi lời hứa bị từ chối (thất bại), đây là kết quả tôi nhận được:

then failure 1: Promise rejected! 
then success 2: from failure 1 
then success 3: from success 2 
then success 5: from success 3 

** Đây là những gì tôi mong đợi (trên một từ chối/Lời hứa thất bại):

then failure 1: Promise rejected! 
then failure 2: from failure 1 
then failure 4: from failure 2 
then failure 5: from failure 4  

Trả lời

11

Bạn chỉ nên quên rằng .then() thậm chí mất hơn 1 đối số và sử dụng phương pháp .catch và nó sẽ có ý nghĩa hơn.

Lời hứa cung cấp sự tương ứng với một số cấu trúc mã đồng bộ hóa nhưng điều này không hiển thị khi bạn chỉ có một mức thấp .then(). Những gì bạn đang tìm kiếm về cơ bản là một mảng callbacks/callback aggregation nhưng đó không phải là điểm hứa hẹn chút nào.

Hãy suy nghĩ về .catch(fn) giống như .then(null, fn):

doSomething().then(function(val) { 
    console.log(val); 
}).catch(function(e) { 
    console.error(e); 
}); 

Parallels mã đồng bộ (tưởng tượng doSomething lợi nhuận đồng bộ):

try { 
    var val = doSomething(); 
    console.log(val); 
} 
catch(e) { 
    console.error(e); 
} 

Nhiều sản lượng đánh bắt (hãy nhớ rằng .catch là bí danh dễ đọc hơn để .then(null, fn)

doSomething().then(function(val) { 
    console.log(val); 
}).catch(function(e) { 
    return e; 
}).catch(function(e){ 
    //Will not get here ever 
    //because error thrown from doSomething() 
    //was handled in the upper catch which doesn't trow 
}); 

Parallels:

try { 
    try { 
     var val = doSomething(); 
     console.log(val); 
    } 
    catch(e) { 
     //no need for explicit return e 
    } 
} 
catch(e) { 
    //Will not get here ever 
    //because error thrown from doSomething() 
    //was handled in the upper catch which doesn't trow 
} 

Vì vậy, bây giờ bạn sẽ nhận thấy rằng bạn có thể tạo ra kết quả mong đợi bằng cách ném thay vì trả lại http://jsfiddle.net/VYSj7/3/

.catch() là IMO một phương pháp cần thiết cho một thư viện hứa sẽ cung cấp và cũng sẽ có bao gồm trong các lời hứa Javascript được tích hợp trong tương lai. Tuy nhiên, nếu phương pháp đó không được cung cấp, bạn có thể (hoặc nên được, tiếc là hiện thực mà không sử dụng nguyên mẫu):

Promise.prototype.catch = function(fn) { 
    return this.then(null, fn); 
}; 

Xem thêm rejection turns into fulfillment

+0

đẹp giải thích, Esailija! Cảm ơn. – RBR

Các vấn đề liên quan