2013-05-30 34 views
8

Tôi đang cố gắng tìm ra một cách tốt để nói "Hãy làm tất cả những điều này, nhưng bảo lãnh trong trường hợp bất kỳ trong số họ thất bại"Dừng một chuỗi AngularJS lời hứa

Những gì tôi có ngay bây giờ:

var defer = $q.defer(); 

this 
    .load(thingy) // returns a promise 

    .then(this.doSomethingA.bind(this)) 
    .then(this.doSomethingB.bind(this)) 
    .then(this.doSomethingC.bind(this)) 
    .then(this.doSomethingD.bind(this)) 

    .then(function(){ 
     defer.resolve(this); 
    }); 
    ; 

return defer.promise; 

Điều tôi muốn cuối cùng là bằng cách nào đó bắt bất kỳ lỗi nào trên chuỗi đó để tôi có thể chuyển nó vào lời hứa defer ở trên. Tôi không đặc biệt quan tâm nếu cú ​​pháp được giữ tương tự như những gì tôi có ở trên.

Hoặc ngay cả khi có ai đó chỉ có thể cho tôi biết cách dừng chuỗi ở trên.

+1

@ user2246674 - từ chối nó dường như không dừng chuỗi mặc dù, tiếp theo chỉ tiếp tục –

+1

Không biết những gì tôi đã suy nghĩ .. – user2246674

+2

Đây là một ví dụ kinh khủng về [antipattern bị trì hoãn] (http: //stackoverflow.com/q/23803743/1048572)! Trục vít mà 'trì hoãn', chỉ' trả về 'this.load (…) .thên (A) .then (B) .then (C) .then (D);' chain! – Bergi

Trả lời

2

Bạn sẽ có thể làm điều đó điều tương tự bởi:

var defer = $q.defer(); 

this 
    .load(thingy) // returns a promise 

    .then(this.doSomethingA.bind(this), $q.reject) 
    .then(this.doSomethingB.bind(this), $q.reject) 
    .then(this.doSomethingC.bind(this), $q.reject) 
    .then(this.doSomethingD.bind(this), $q.reject) 

    .then(defer.resolve.bind(defer, this), defer.reject.bind(defer)); 
    ; 

return defer.promise; 
+3

Câu trả lời này sử dụng tính năng chống mẫu và khiến người dùng lặp lại xử lý lỗi. –

0

Được rồi, việc này nhưng tôi không thích nó ... Đang chờ một cái gì đó tốt hơn :)

Nó chỉ có vẻ bẩn để tạo ra một lời hứa vì lợi ích duy nhất của ngay lập tức từ chối nó

myApp 
    .factory('chainReject', [ '$q', function($q){ 
     return function(err){ 
      var defer = $q.defer(); 
      defer.reject(err); 

      return defer.promise; 
     } 
    } ]); 

... 

var defer = $q.defer(); 

this 
    .load(thingy) // returns a promise 

    .then(this.doSomethingA.bind(this), chainReject) 
    .then(this.doSomethingB.bind(this), chainReject) 
    .then(this.doSomethingC.bind(this), chainReject) 
    .then(this.doSomethingD.bind(this), chainReject) 

    .then(defer.resolve.bind(defer, this), defer.reject.bind(defer)); 
    ; 

return defer.promise; 
5

Bạn có thể ngừng chuỗi góc cạnh bằng cách trả lại lời hứa bị từ chối bên trong bất kỳ cuộc gọi lại nào.

load() 
.then(doA) 
.then(doB) 
.then(doC) 
.then(doD); 

nơi DOA, DOB, DOC, DOD thể có logic như thế này:

var doA = function() { 
    if(shouldFail) { 
     return $q.reject(); 
    } 
} 
+1

+1 Điều gì đã xảy ra với tôi là phần 'return' của' return $ q.reject() '. Rất nhiều tìm kiếm dẫn đến tất cả các cách khác nhau, nhưng thực sự trả lại $ q.từ chối() thay vì chỉ gọi nó là những gì thực sự giết chết chuỗi. Đặc biệt là nếu bạn đang cố gắng làm một cái gì đó không phải là một lỗi HTTP, nhưng một 'thất bại' theo nghĩa là mô hình trở lại với một phản ứng tiêu cực dự kiến. – coblr

+0

Một cách khác để ngăn chặn chuỗi, giả sử bạn muốn hiển thị lỗi xảy ra trong quá trình thực hiện chuỗi, bạn chỉ có thể 'ném lỗi mới() ' –

+0

Lời hứa bị từ chối trả về sẽ không dừng chuỗi. – user3631341

3

Tôi chỉ cần stumbled trên này và nhận ra tất cả những câu trả lời là khủng khiếp lỗi thời. Đây là cách thích hợp để xử lý việc này cho bất kỳ ai có thể tìm thấy bài đăng này.

// Older code 
return this.load(thing) 
    .then(this.doA, $q.reject) 
    .then(this.doB, $q.reject) 
    .then(this.doC, $q.reject) 
    .then(this.doD, $q.reject) 
    .then(null, $q.reject); 


// Updated code 
// Returns the final promise with the success handlers and a unified error handler 
return this.load(thing) 
    .then(this.doA) 
    .then(this.doB) 
    .then(this.doC) 
    .then(this.doD) 
    .catch(this.handleErrors); // Alternatively, this can be left off if you just need to reject the promise since the promise is already rejected. 
    // `.catch` is an alias for `.then(null, this.handleErrors);` 
+0

'.catch' không tồn tại trong '$ q' của góc cạnh khi câu hỏi này được hỏi :) –

+0

@zyklus, bạn đúng nhưng' .catch' chỉ là một bí danh cho '.then (null, fn)'. Mà nên có giá trị sau đó. –

+0

Nó đã không được sử dụng để vượt qua các lỗi thông qua, nghĩa là nó sẽ chỉ bắt lỗi từ trước đó 'sau đó', đó là lý do tại sao tôi đã viết tất cả các chuỗi từ chối vô nghĩa dưới đây. –

0

Cách tốt nhất để xử lý vấn đề này và cũng để nắm bắt vấn đề là khối .catch. Bên trong bất kỳ khối .Sau đó mà bạn muốn giết chuỗi lời hứa, có sử dụng:

return $q.reject(); 

Tuy nhiên mở rộng nó như vậy ...

return $q.reject(new Error('Error Message Here')); 

Bây giờ trong phương pháp đánh bắt, bạn sẽ có điều này

.catch(function(err) { 
    console.log(err); //This will log the above 'Error Message Here' 
}); 

Bây giờ chúng tôi ném và xử lý lỗi chính xác trong các lỗi hứa hẹn thời trang đã có nghĩa là để được xử lý.

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