frontend-document icon indicating copy to clipboard operation
frontend-document copied to clipboard

[JS] [2021-01-09 更新] 介绍下 promise的特性、优缺点?

Open jeddygong opened this issue 3 years ago • 1 comments

jeddygong avatar Jan 08 '21 16:01 jeddygong

Promise基本特性

  • Promise 有三种状态;pending(进行中)、fulfilled(已成功)、rejected(已失效);
  • Promise 对象接受一个回调函数作为参数,该回调函数接受两个参数,分别是成功时的回调resolve和失败时的回调reject;另外resolve的参数除了正常值以外,还可能是一个Promise对象的实例;reject的参数通常是一个Error对象的实例。
  • then方法返回一个新的Promise实例,并接受两个参数onResolved(fullfilled状态的回调)、onRejected(rejected状态的回调,该参数可选)
  • catch方法返回一个新的Promise实例;
  • finally方法不管Promise转态如何都会执行,该方法的回调函数不接受任何参数;
  • Promise.all() 方法将多个Promise实例,包装成一个新的Promise实例,该方法接受一个由Promise对象组成的数组作为参数(Promise.all()方法的参数可以不是数组,但必须具有iterator接口,且返回的每个成员都是Promise实例),注意参数中只要有一个实例触发catch方法,都会触发Promise.all()方法返回的新的实例的catch方法,如果参数中的某个实例本身调用了catch方法,将不会触发Promise.all()方法返回的新势力的catch方法;
  • Promise.race()方法的参数与Promise.all方法一样,参数中的实例只要有一个率先改变状态就会将该实例的状态传给Promise.race()方法,并将返回值作为Promise.race()方法生产的Promise实例的返回值;
  • Promise.resolve()将现有对象转化为Promise对象,如果该方法的参数为一个Promise对象,Promise.resolve()将不做任何处理;如果参数thenable对象(即具有then方法),Promise.resolve()将该对象转为Promise对象并立即执行then方法;如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为fulfilled,其参数将会作为then方法中onResolved回调函数的参数,如果Promise.resolve方法不带参数,会直接返回一个fulfilled状态的Promise对象。需要注意的是,立即resolve()的Promise对象,是在本轮“事件循环”(Event loop) 的结束时执行,而不是在下一轮“事件循环”的开始时。
  • Promise.reject()同样返回一个新的Promise对象,状态为rejected, 无论传入任何参数都将作为reject()的参数。

Promise优点

  • ① 统一异步API
    • Promise的一个重要优点是它将逐渐被用作浏览器的异步API,统-现在各种各样的API以及不兼容的模式和手法。
  • ② Promise 与事件对比
    • 和事件相比较, Promise更适合处理一-次性的结果。在结果计算出来之前或之后注册回调函数都是可以的,都可以拿到正确的值。
    • Promise的这个优点很自然。但是,不能使用Promise处理多次触发的事件。链式处理是Promise的又-优点,但是事件却不能这样链式处理。
  • ③ Promise 与回调对比
    • 解决了回调地狱的问题,将异步操作以同步操作的流程表达出来。
  • ④ Promise带来的额外好处是包含了更好的错误处理方式(包含了异常处理),并且写起来很轻松(因为可以重用一些同步的工具,比如Array.prototype.map() )。

Promise缺点

  • 1、无法取消Promise, 一旦新建它就会立即执行,无法中途取消。
  • 2、如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 3、当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
  • 4、Promise真正执行回调的时候,定义Promise那部分实际上已经走完了,所以Promise的报错堆栈上下文不太友好。

jeddygong avatar Jan 13 '21 15:01 jeddygong