Promise需要注意的几点

2019-04-01  本文已影响0人  浩神

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) => { ... }) 这里的结果可能是:

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函数抛出的异常。

上一篇 下一篇

猜你喜欢

热点阅读