Làm thế nào để từ chối một lời hứa từ bên trong sau đó hoạt động


85

Đây có lẽ là một câu hỏi ngớ ngẩn, nhưng chuỗi hứa giữa, làm thế nào để bạn từ chối một lời hứa từ bên trong một trong các hàm then? Ví dụ:

someActionThatReturnsAPromise()
    .then(function(resource) {
        return modifyResource(resource)
    })
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource)) {
            var validationError = getValidationError(modifiedResource);
            // fail promise with validationError
        }
    })
    .catch(function() {
        // oh noes
    });

Không còn tham chiếu đến chức năng giải quyết / từ chối ban đầu hoặc PromiseResolver. Tôi chỉ cần thêm vào return Promise.reject(validationError);?


1
throw validationError
kavun

> <Tôi có cảm giác rằng nó sẽ là một cái gì đó ngớ ngẩn / dễ dàng như vậy. Đoán rằng tôi đã tiếp tục nghĩ rằng tôi phải gọi một hàm từ chối chuyên dụng hoặc trả về một Lời hứa không thành công. Vì vậy, từ bên trong một lời hứa / có thể, bất kỳ giá trị trả về nào không phải là một Lời hứa mới sẽ được coi là giá trị đã phân giải? Và nếu tôi mắc lỗi, điều đó cũng giống như việc trả lại một Lời hứa bị từ chối ngay lập tức? Nếu bạn đăng nó như một câu trả lời, tôi sẽ chấp nhận nó.
chinabuffet

Bạn có thể đang tìm kiếm câu trả lời được chấp nhận ở đây stackoverflow.com/questions/17800176/…
crad

Câu trả lời:


96

Tôi chỉ cần thêm vào return Promise.reject(validationError);?

Đúng. Tuy nhiên, nó phức tạp chỉ trong jQuery, với thư viện tương thích với Promise / A +, bạn cũng có thể đơn giản

throw validationError;

Vì vậy, mã của bạn sau đó sẽ giống như

someActionThatReturnsAPromise()
    .then(modifyResource)
    .then(function(modifiedResource) {
        if (!isValid(modifiedResource))
            throw getValidationError(modifiedResource);
        // else !
        return modifiedResource;
    })
    .catch(function() {
        // oh noes
    });

3
Đây có phải là việc thường xuyên phải làm không? Nó có được sử dụng rộng rãi không? Tôi cảm thấy xấu làm việc đó, bởi vì nếu ở đâu đó trong các mã .catchlà mất tích, các toàn bộ ứng dụng sẽ thổi lên với lỗi unhalted ..
Andrey Popov

3
Lưu ý rằng trong thư viện tuân thủ Promise / A +, bạn có thể sử dụng ném vì handlerfor thenlà đồng bộ hóa và ngoại lệ có thể được xử lý. Nếu trình xử lý không đồng bộ, nó phải trả về một lời hứa để cuối cùng từ chối. Vì vậy, luôn luôn trả về Promise.reject () thay vì ném có ý nghĩa đối với tôi. Bởi vì nếu bạn ném vào một trình xử lý không đồng bộ, thư viện không thể bắt được nó và nó sẽ âm thầm trôi qua. Hãy coi chừng.
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: Không nên có trình xử lý không đồng bộ không phải là .thentrình xử lý theo lời hứa :-) Nếu bạn đang sử dụng một API không được quảng bá, thì thậm chí return Promise.reject()sẽ giúp bạn.
Bergi

@Bergi Ý tôi là: p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); EDIT: ồ được rồi, tôi đọc lại bình luận của bạn, tôi hoàn toàn đồng ý với bạn, chúng ta ở cùng một trang! Tôi muốn chỉ ra cho OP :)
Mike Gleason jr Couturier

1
@MikeGleasonjrCouturier: Vâng, đó chính xác là những gì tôi đã nói. Và doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })cũng không hoạt động ở đó - nó chỉ âm thầm thất bại. Nó thực sự nên có doAsync().then(function() { throw new Error("will be caught"); })khi bạn làm việc với những lời hứa.
Bergi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.