如何从内部拒绝承诺然后起作用


85

这可能是一个愚蠢的问题,但是在诺言链中间,您如何从then函数之一内部拒绝诺言呢?例如:

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
    });

不再引用原始的解析/拒绝函数或PromiseResolver。我应该补充return Promise.reject(validationError);吗?


1
throw validationError
kavun 2014年

> <我有种感觉,这很愚蠢/容易。猜猜我一直在想,我必须调用专用的拒绝函数或返回失败的Promise。因此,从一个promise / thenable内部,任何不是新Promise的返回值都将被视为已解决值?如果我抛出错误,那与返回立即被拒绝的Promise一样?如果您将其发布为答案,我会接受。
chinabuffet 2014年

您可能正在这里寻找可接受的答案stackoverflow.com/questions/17800176/…–
crad

Answers:


96

我应该补充return Promise.reject(validationError);吗?

是。但是,只有在jQuery中如此复杂,有了Promise / A +兼容的库,您也可以简单地

throw validationError;

所以你的代码看起来像

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

3
这是正常的事情吗?它被广泛使用吗?我这样做很不好,因为如果代码中的某处.catch丢失,整个应用程序将崩溃,并且出现无法终止的错误。.–
Andrey Popov

3
请注意,在Promise / A +兼容库中,可以使用throw,因为handlerforthen是同步的,并且可以捕获异常。如果处理程序是异步的,则它必须返回一个诺言以最终拒绝。因此,始终返回Promise.reject()而不是抛出对我来说很有意义。因为如果您抛出一个异步处理程序,该库将无法捕获它,并且它将以静默方式通过。谨防。
Mike Gleason jr Couturier 2015年

1
@MikeGleasonjrCouturier:应该没有异步处理程序,不是.then承诺的处理程序:-)如果您使用的是未承诺的API,那么它甚至return Promise.reject()会对您有所帮助。
Bergi 2015年

@Bergi我的意思是:p.then(function() { doAsync(function() { throw new Error("won't catch"); }); }); 编辑:哦,好的,我重新阅读了您的评论,我完全同意您的意见,我们在同一页面上!我想将其指出给OP :)
Mike Gleason jr Couturier 2015年

1
@MikeGleasonjrCouturier:是的,这正是我在说的。而且doAsync(function() { return Promise.reject(new Error("won't catch, won't throw")); })在那里也不起作用-它只是默默地失败。确实应该doAsync().then(function() { throw new Error("will be caught"); })在您兑现承诺的时候。
Bergi 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.