1. Promise 是对异步结果的表示
A promise represents the eventual result of an asynchronous operation.
From Promises/A+规范
与其说Promise是来写异步代码的,不如说Promise提供了对异步操作的结果的管理。正如上面引用的Promises/A+规范里面说定义的: Promise表示异步操作的最终结果。
MDN上的描述更详细地描述了Promise的本质:
Promise 对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象
对于new Promise((resolve, reject) => { ... })
这里的结果可能是:
- fulfilled:异步操作成功完成了(遇到 resolve调用)
- rejected: 失败了(遇到 reject调用或者代码执行出异常)
Promise向我们保证(promise),异步操作的结果不会发生变化,只能从最开始的pending态变成fulfilled态,或者从最开始的pending态变成rejected态。一旦变成fulfilled或者rejected就不会再变了。
new Promise((resolve, reject) => {
resolve(123); // 异步操作结果变为fullfilled
console.log('代码还会执行');
reject(321); // 无法改变结果了
console.log('代码还会执行');
})
.then(console.log)
.catch(console.error)
上面的代码执行完会变成:
没有catch到异常但我们需要注意的一点是:
Promise内的异步代码遇到resolve()或者reject()就会确定最终的操作结果,但代码还会继续执行
2. 如果不写catch, Promise会吞异常
new Promise((resolve, reject) => {
console.log('代码执行')
throw new Error('ERROR') // 执行到这里,操作结果变为Rejected,代码执行结束
resolve(321);
throw new Error('eeeee')
console.log('代码不会执行')
})
.then(console.log)
以上代码的执行结果是,控制台只打印“代码执行”。
遇到内部异常,代码会停止执行,但不会对外抛出异常,除非我们在Promise后边的链式操作中手动捕获。(PS: node环境中会报一个warning)
3. Promise.then()接受第二个参数,能处理之前的异常。
promise.then(onFulfilled, onRejected)
new Promise((resolve, reject) => {
console.log('代码执行')
throw new Error('ERROR')
resolve(321)
})
.then(console.log, (err) => {
console.log("捕获到异常")
return "我还是悄悄处理掉吧"
})
.then(console.log)
.catch(() => console.log('没人管的异常'))
执行结果如下:
异常被then处理了Promise.then第二个参数处理异常的用处在于,我不想中断整个链式操作,在异常情况之下,我还可以做一些兼容处理。当然,中间嵌入一个 .catch() 也能实现这种兼容处理。但把catch放在链式操作最后,仅仅象征性地处理最后没人管的异常显然更美观。
另外需要注意的是对于promise.then(onFulfilled, onRejected)第二个参数函数,它只能处理then之前的异常,而不能处理当前then中 onfulFilled函数抛出的异常。
网友评论