Promise 的理解和使用
Promise 是什么
- 抽象理解
Promise
是一门新的技术(ES6
规范)Promise
是JS
中进行异步编程的新解决方案(旧方案是单纯使用回调函数)
- 具体理解
- 语法上:
Promise
是一个构造函数 - 功能上:
Promise
对象用来封装一个异步操作并可以获取其成功/失败的结果值
- 语法上:
Promise 在使用上有哪些优势
- 指定回调函数的方式更加灵活
promise
的使用过程是:启动异步任务 =>返回promie
对象 =>给promise
对象绑定回调函数(甚至可以在异步任务结束后指定/多个)- 之前的回调函数方式,必须在启动异步任务前指定
- 支持链式调用,可以解决回调地狱问题
- 什么是回调地狱
回调函数嵌套调用,外部回调函数异步执行的结果是嵌套的回调执行的条件 - 回调地狱的缺点
- 不便于阅读
- 不便于异常处理
- 什么是回调地狱
promise 的状态及值
- Promise 的状态是实例对象中的一个属性【
promiseState
】pending
变为resolved
(或fullfilled
):成功状态pending
变为rejected
:失败状态
只有这2种,且一个promise
对象只能改变一次无论变为成功还是失败,都会有一个结果数据
注:成功的结果数据一般称为 value,失败的结果数据一般称为reason
- Promise 对象的值是实例对象中的另一个属性【
PromiseResult
】
保存着对象「成功/失败」的结果resolve
reject
Promise 的工作流程
如何使用 Promise
API
Promise
构造函数:Promise(excutor){}
executor
函数:执行器(resolve, reject)=>{}
resolve
函数:内部定义成功时我们调用的函数value =>{}
reject
函数:内部定义失败时我们调用的函数reason =>{}
- 说明:
executor
会在Promise
内部立即同步调用,异步操作在执行器中执行
Promise.prototype.then
方法:(onResolved, onRejected) => {}
onResolved
函数:成功的回调函数(value) =>{}
onRejected
函数:失败的回调函数(reason) =>{}
- 说明:指定用于得到成功
value
的成功回调和用于得到失败reason
的失败回调
返回一个新的promise
对象
Promise.prototype.catth
方法:(onRejected) => {}
onRejected
函数:失败的回调函数(reason)=>{)()
- 说明:
then()
的语法糖,相当于:then(undefined, onRejected)
Promige.resolve
方法:(value) => {}
value
:成功的数据或promise
对象- 说明:返回一个成功/失败的
promise
对象 - 如果传入的参数为
非Promise
类型的对象,则返回的结果为成功promise
对象 - 如果传入的参数为
Promise
对象,则参数的结果决定了resolve
的结果
Promise.reject
方法:(reason) =>{}
reason
:失败的原因- 说明:返回一个失败的
promise
对象
Promise.all
方法:(promises) =>{}
promises
:包含n个propnise
的数组- 说明:返回一个新的
promise
,只有所有的promise
都成功才成功,只要有一个失败了就直接失败
Promise.race
方法:(promises) =>{}
promises
:包含n个promise
的数组- 说明:返回一个新的
promise
,第一个完成的promise
的结果状态就是最终的结果状态
Promise 的关键问题
如何改变 promise 的状态
resolve(value)
:如果当前是pending
就会变为resolved
reject(reason)
:如果当前是pending
就会变为rejected
- 抛出异常:如果当前是
pending
就会变为rejected
let p=new Promise((resolve, reject) => { //1.resolve 函数 resolve('ok'); // pending=>fulfilled(resolved) //2.reject 函数 reject("error");//pending => rejected //3.抛出错误 throw'出问题了'; })
一个 promise 指定多个成功/失败回调函数,都会调用吗
- 当
promise
改变为对应状态时都会调用
- 当
改变 promise 状态和指定回调函数谁先谁后
- 都有可能,正常情况下是先指定回调再改变状态,但也可以先改状态再指定回调
- 如何先改状态再指定回调
- 在执行器中直接调用
resolve()/reject()
- 延迟更长时间才调用
then()
- 在执行器中直接调用
- 什么时候才能得到数据
- 如果先指定的回调,那当状态发生改变时,回调函数就会调用,得到数据
- 如果先改变的状态,那当指定回调时,回调函数就会调用,得到数据
promise.then()返回的新 promise 的结果状态由什么决定
- 简单来说: 由 then() 指定的回调函数执行的结果决定
- 具体分析:
- 如果抛出异常,新
promise
变为rejected, reason
为抛出的异常 - 如果返回的是非
promise
的任意值,新promise
变为resolved,value
为返回的值 - 如果返回的是另一个新
promise
,此promise
的结果就会成为新promise
的结果
- 如果抛出异常,新
promise 如何串连多个操作任务
promise
的then()
返回一个新的promise
,可以形成then()
的链式调用- 通过
then
的链式调用串连多个同步/异步任务
promise 异常传透
- 当使用
promise
的then
链式调用时,可以在最后指定失败的回调 - 前面任何操作出了异常,都会传到最后失败的回调中处理
let p = new Promise((resolve, reject)=>{setTimeout(()=>{ reject('Err'); },1000); }); p .then(value =>{console.log(111);}) .then(value =>{console.log(222);}) .then(value =>{console.log(333);}) .catch(reason·=>·{console.warn(reason);}) // 只需要在最后catch错误即可
- 当使用
如何中断 promise 链
- 当使用
promise
的then
链式调用时,在中间中断,不再调用后面的回调函数 - 方法: 在回调函数中返回一个
pendding
状态的promise
对象
let p = new Promise((resolve, reject)=>{ resolve('OK') }); p .then(value =>{ console.log(111); //有且只有一个方式可中断 promise 链,后续的回调将不再执行 return new Promise(()=>{}); }) .then(value =>{console.log(222);}) .then(value =>{console.log(333);}) .catch(reason·=>·{console.warn(reason);})
- 当使用