【ES6+】Promise对象超实用上手指南

为什么使用Promise:

在传统的异步编程中,如果异步之间存在依赖关系,只能使用层层嵌套的回调函数来满足这种依赖,如果嵌套的层数过多,降低可读性和可维护性,产生所谓的“回调地狱”。

Promise提供了全新的异步编程的一种解决方案。将回调嵌套改为链式调用,将异步的操作以同步操作的方式表达出来。

简单释义:

Promise是一个对象,可以理解为一个状态机,保存着某个未来才会结束的事件的结果。从而可以获取异步操作的消息。它提供了统一的API。

Promise A+规范:

两个核心规则:

  1. Promise本质是一个状态机,有3种状态:Pending(等待态)、Fulfilled(执行态)、Rejected(拒绝态),而且状态的变更是单向的,只能从Pending -> Fulfilled 或 Pending -> Rejected,状态变更不可逆;
  2. then()方法接收两个可选参数,分别对应状态改变时触发的回调。then方法返回一个promise。then 方法可以被同一个 promise 调用多次。

缺点

  1. 一旦创建实例,无法取消,会立即执行;
  2. 在pending状态改变之前,无法知道进度(是才开始,还是即将结束)
  3. 对比rx,不能吐出多个值。

执行机制

new的实例会立即执行,resolve和reject异步回调函数会在本次事件循环结束后才会执行。
执行流程

基本用法:

Promise对象是一个构造函数,故使用new操作符生成一个Promise实例。

最简单的Promise的使用:

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('result')
    },
    1000);
})

p1.then(res => console.log(res), err => console.log(err))

语法:

new Promise(executor: (resolve: (value?: any) => void, reject: (reason?: any) => void) => void): Promise<any>
Promise<any>.then<any, never>(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => PromiseLike<never>): Promise<any>

分析Promise的调用流程:

  1. 构造函数接受衣蛾executor(),在new Promise()时会立即执行这个回调函数;
  2. executor()内部的异步任务被放入宏/微任务队列,等待执行;
  3. 调用then()时,会收集resolve/reject回调函数,放入成功/失败队列;
  4. 当executor()的异步任务被执行,触发resolve/reject,从成功/失败队列中取出回调依次执行。
观察者模式

收集依赖 -> 触发通知 -> 取出依赖执行 的方式,被广泛运用于观察者模式的实现,在Promise里,执行顺序是 then收集依赖 -> 异步触发resolve -> resolve执行依赖

常用API

API作用
Promise.prototype.then()第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数,返回一个新的Promise实例
Promise.prototype.catch()指定发生错误时的回调函数,错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个catch语句捕获
Promise.prototype.finally()不管 Promise 对象最后状态如何,都会执行的操作,这是ES2018引入标准的
Promise.all()将多个 Promise 实例,包装成一个新的 Promise 实例;(所有成功才成功,一个失败就失败)
Promise.race()同样是将多个 Promise 实例,包装成一个新的 Promise 实例(最后的状态取决于最先改变状态的实例)
Promise.allSettled()有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束,,而且状态总是fulfilled(这是ES2020引入)
Promise.any()接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例(所有失败才失败,衣蛾成功就成功)
Promise.resolve()将现有对象转为 Promise 对象
Promise.reject()返回一个新的 Promise 实例,该实例的状态为rejected

异常处理

分析问题:

  1. 如果没有使用catch方法指定错误处理的回调函数,Promise 对象抛出的错误不会传递到外层代码,不会退出进程、终止脚本执行,即不会有任何反应;
  2. Promise 内部的错误不会影响到 Promise 外部的代码,通俗的说法就是“Promise 会吃掉错误”。

处理方式

  1. 一般总是建议,Promise 对象后面要跟catch方法,这样可以处理 Promise 内部发生的错误;
  2. then()和catch()要成对出现,then在前,catch在后.。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值