持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情
前言
我们都知道JavaScript是执行环境为“单线程”语言。这样虽然实现比较简单,但一旦有一个耗时特别长的任务,就会阻碍整个程序的正常运行。就跟超市收银只有一个队一样,前面有人买了一大堆东西,后面的人只能等他,整体的进度就被拖慢了。那该怎么解决这种问题呢?答案是异步编程。按前面那个例子来看,就是咱把东西多的人分到第二队去,就是同步的代码正常执行,异步的先到旁边自己执行(不按照代码顺序去执行),最后程序的执行时间大大减少。那么,异步编程有几种方案呢?一就是回调函数,二就是本文讲的Promise
Promise对象
什么是Promise
所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。 ---------- 《ES6 入门教程》
Promise的基本用法
语法: const a=new Promise((resolve,reject)=>{})
参数: Promise接收两个函数作为参数,一个是resolve,作用是将Promise对象的状态从Pending转为fulfilled,并将异步操作的结果(可以是值,也可以是另一个Promise对象)作为结果传递出去。一个是reject,作用是将从Pending转为rejected,将抛出的错误传递出去。
Promise有三种状态:Pending,fulfilled,rejected且只有两种转换方式
1.
Pending=>fulfilled2.
Pending=>rejected
基本使用:
1 .resolve:
首先then的作用是为 Promise 实例添加状态改变时的回调函数,并且then方法的第一个参数是fulfilled状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
let a=new Promise((resolve,reject)=>{
resolve(1) //同步执行并向外部传递异步操作的结果
}).then((fulfilled)=>{
console.log(fulfilled) //等所有同步代码执行完按异步队列先后顺序去执行
}) //1
- reject:
catch()方法是then(null, rejection)或then(undefined, rejection)的别名,用于指定发生错误时的回调函数。在reject抛出错误,或运行出现错误时都会调用此方法的回调函数。
let a=new Promise((resolve,reject)=>{
reject(new Error("error"))
}).catch((rejected)=>{
console.log(rejected)
}) //Error: error......
Promise的其他方法
Promise.prototype.finally():用法为不管 Promise 对象最后状态如何,都会执行指定操作
Promise.all():将多个 Promise实例,包装成一个新的 Promise 实例,只有当其中所有的Promise实例状态皆为fulfilled新的实例才会变为fulfilled
Promise.race():同样将多个Promise 实例,包装成一个新的 Promise 实例。但只要有一个Promise 实例状态改变,新的实例便跟着改变
promise 的几个关键问题
如何改变 promise 的状态?
(1)resolve(fulfilled): 如果当前是 pending 就会变为 resolved
(2)reject(rejected): 如果当前是pending 就会变为 rejected
(3) 抛出异常: 如果当前是 pending 就会变为 rejected
一个 promise 指定多个成功/失败回调函数, 都会调用吗?
当 promise 改变为对应状态时都会调用
改变 promise 状态和指定回调函数谁先谁后?
(1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
(2) 如何先改状态再指定回调?
① 在执行器中直接调用 resolve()/reject()
② 延迟更长时间才调用then()
(3) 什么时候才能得到数据?
① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
promise.then()返回的新promise 的结果状态由什么决定?
(1) 简单表达: 由 then()指定的回调函数执行的结果决定
(2) 详细表达:
① 如果抛出异常, 新 promise变为rejected, rejected为抛出的异常
② 如果返回的是非 promise 的任意值, 新 promise 变为resolved, fulfilled为返回的值
③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
promise 如何串连多个操作任务?
(1) promise 的 then()返回一个新的 promise, 可以继续 then()的链式调用
(2) 通过 then() 的链式调用串连多个异步任务
promise 异常穿透?
(1) 当使用 promise 的 then() 链式调用时, 可以在最后指定失败的回调,
(2) 前面任何操作出了异常, 都会传到最后失败的回调中处理
中断 promise 链?
(1) 当使用 promise 的 then() 链式调用时, 在中间中断, 不再调用后面的回调函数
(2) 办法: 在回调函数中返回一个 pending 状态的 promise 对象