当一个Promise
被拒绝,而.then()
在.catch()
之后出现时,就会捕捉到拒绝,但是下面仍然会运行(参见下面的then
示例)。
但是,当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'
函数。
发布于 2017-10-11 13:46:35
它类似于传统的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));
这要么显示从example.com
获取的example.com
,要么显示default value
。
发布于 2017-10-11 14:17:31
不会调用任何catch
(实际上在then
中没有第一个回调,因为第二个回调确实是catch的替代),直到您在链中“捕获拒绝”并返回“正”值-- then
函数应该返回任何未解决的承诺,并且不应该抛出和错误来“修复”该链中的承诺。如果catch
将返回这样的值,那么下一个then
将被调用,它也将获得作为param的catch
的返回值。同样,如果then
被调用并抛出错误或返回被拒绝的承诺,则在“捕获拒绝”之前不会调用链中的下一个then
。
例如。
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'.
这就是承诺链的工作原理--通过捕捉拒绝原因并返回一些不是错误的内容,您可以从被拒绝的承诺得到解决,还可以通过返回被拒绝的承诺或在附加的then
中抛出错误来“破坏”已解决的承诺。
这是非常强大的特性,在您的实现中,您可以决定在拒绝时做什么,所以如果您要做这样的事情(没有catch
es):somePromise.then().then().then()
意味着如果在任何阶段发生错误,您都不想调用任何后续的then
回调。但是,如果您想处理某些then
上的承诺拒绝,则在这个then
之后添加catch
。
它类似于try/catch --如果在此块中的前一行中抛出异常,则不会调用try块中的部分代码。
顺便说一句,修正了你的小提琴例子:https://jsfiddle.net/ro0cv1p1/3/
https://stackoverflow.com/questions/46687558
复制相似问题