美文网首页
Promise需要注意的几点

Promise需要注意的几点

作者: 浩神 | 来源:发表于2019-04-01 18:22 被阅读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) => { ... }) 这里的结果可能是:

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

    相关文章

      网友评论

          本文标题:Promise需要注意的几点

          本文链接:https://www.haomeiwen.com/subject/xqlbbqtx.html