当Promise被拒绝时,Promise连锁订单有什么用?

时间:2017-10-11 11:53:07

标签: javascript

Promise被拒绝,而.then().catch()之后,拒绝被捕获,但接下来仍会运行(请参阅下面的then示例)。< / p>

但是,如果Promise已解决且.then()位于.catch()之前,则会拒绝拒绝,并且永远不会调用.then()

为什么这两种情况的行为方式不同,以及在发生拒绝后进行.then()调用会有什么用处?

var then = Promise.reject()
    .catch(() => 'catch')
    .then(() => document.getElementById('then').innerHTML = 'then');

var noThen = Promise.reject()
    .then(() => document.getElementById('noThen').innerHTML = 'then')
  .catch((err) => 'catch');

https://jsfiddle.net/mmyj61dd/

编辑:

一个有趣的相关示例,说明了依赖.then()如何依赖于它传递的函数的参数:

var then = Promise.reject()
  .then((undefined, err) => 'catch')
  .then((asdf) => document.getElementById('then').innerHTML = 'then');

var noThen = Promise.reject()
  .then((asdf) => document.getElementById('noThen').innerHTML = 'then')
  .then((undefined, err) => 'catch');

在这两种情况下,只有(undefined, err) => 'catch'函数被调用。

https://jsfiddle.net/ro0cv1p1/2/

2 个答案:

答案 0 :(得分:2)

它类似于传统的try..catch

try {
    foo();
    bar();
} catch (e) {
    baz();
}

这与以下不同:

try {
    foo();
} catch (e) {
    baz();
}

bar();

实际应用程序很容易解释:尝试一些事情(启动一个承诺),如果失败则产生一些默认值,然后继续使用异步链。例如:

fetch('http://example.com')
    .then(result => result.somevalue)
    .catch(e => 'default value')
    .then(value => alert(value));

这会显示从somevalueexample.com获取的default value

答案 1 :(得分:1)

没有then(实际上没有then中的第一个回调,因为第二个回调确实是catch的替代方法)将被调用,直到你在链中“捕获拒绝”并返回“正”值 - < strong> catch函数应该返回任何未解决的Promise并且不应该抛出错误来“修复”链中的Promise。 如果catch将返回此类值,则会调用then,它也将获得catch作为参数的返回值。 同样,如果调用then并抛出错误或返回被拒绝的Promise,则链中的下一个then将在“捕获拒绝”之前被调用。

E.g。

let resolvedPromiseAfterAll = Promise.reject()
    .then(() => 'then') // <-not called
    .catch(e => { console.log(e); throw e; }) // <- only error log
    .then(() => 'then 2') // <- still not called because previous catch didn't resolve the promise
    .catch(e => 'catched') // <- return 'catched' that is equiv to Promise.resolve('catched')
    .then(val => { console.log('then 2', val); return 'ok'; }) // <-- this promise should finally be called because previous catch didn't throw Error or returned rejected Promise. We also get 'catch' as first param in then callback so the console.log is 'then 2 catched'.

这就是Promise链的工作原理 - 你可以从被拒绝的Promise中获得解决,通过捕获拒绝原因并返回一些不是错误的东西,并且你可以通过返回被拒绝的Promise或者在附加的{{1中抛出错误'来“破解”已解决的Promise }}

这是一个非常强大的功能,在你的实现中你决定如何处理拒绝,所以如果你做这样的事情(没有then es): catch 表示如果在任何阶段出现问题,您不希望调用以下任何somePromise.then().then().then()回调。 但是,如果您想在某些then上处理承诺拒绝,请在then之后添加catch

它与try / catch类似 - 如果在此块的前一行中抛出异常,则不会调用try块中的某些代码部分。

顺便说一下,修正了你的小提琴示例:https://jsfiddle.net/ro0cv1p1/3/