3.4 Promise.resolve 方法
Promise.resolve 方法: (value) => {}
- value: 成功的数据或 promise 对象
返回一个成功/失败的 promise 对象
// 如果传入的参数为 非Promise类型的对象, 则返回的结果为成功promise对象 const p1 = Promise.resolve( 123 ) console.log(p1) // 如果传入的参数为 Promise 对象, 则参数的结果决定了 resolve 的结果 const p2 = Promise.resolve( new Promise( (resolve, reject)=>{ resolve('ok') } ) ) console.log(p2); const p3 = Promise.resolve( new Promise( (resolve, reject)=>{ reject('error') } ) ) console.log(p3);
3.5 Promise.reject 方法
Promise.reject 方法: (reason) => {}
- reason: 失败的原因
返回一个失败的 promise 对象
const p1 = Promise.reject( new Promise((resolve, reject)=>{ resolve('ok') }) ) console.log(p1)
3.6 Promise.all 方法
Promise.all 方法: (promises) => {}
- promises: 包含 n 个 promise 的数组
返回一个新的 promise, 只有所有的 promise 都成功才成功, 只要有一个失败了就直接失败
const p1 = Promise.resolve('OK') const p2 = Promise.reject('Error') // 处理失败,防止报错 p2.catch( reason=>{} ) const p3 = new Promise( (resolve, reject)=>{ resolve('ok') } ) // p1 p3 的状态为成功,p2 为失败,res1的状态为失败 const res1 = Promise.all( [p1, p2, p3] ) // 处理失败,防止报错 res1.catch( reason=>{} ) // p1 p3 的状态为成功,res2的状态为成功 const res2 = Promise.all( [p1, p3] ) console.log( res1 ) console.log( res2 )
3.7 Promise.race 方法
Promise.race 方法: (promises) => {}
- promises: 包含 n 个 promise 的数组
返回一个新的 promise, 第一个完成的 promise 的结果状态就是最终的结果状态
const p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 1000) }) const p2 = Promise.resolve('ok') const p3 = Promise.reject('err') const res = Promise.race([p1, p2, p3]) console.log(res)
第一个完成的Promise为 p2
p2状态为成功,最后结果为成功
4. promise 的几个关键问题
4.1 如何改变 promise 的状态
- (1) resolve(value): 如果当前是 pending 就会变为 resolved
- (2) reject(reason): 如果当前是 pending 就会变为 rejected
- (3) 抛出异常: 如果当前是 pending 就会变为 rejected
let p = new Promise( (resolve, reject)=>{ resolve('ok') } ) // resolve -- 成功 console.log(p) p = new Promise( (resolve, reject)=>{ reject('ok') } ) // reject -- 失败 console.log(p) p = new Promise( (resolve, reject)=>{ throw 'err' } ) // 抛出错误为失败 console.log(p)
4.2 一个 promise 指定多个成功/失败回调函数
一个 promise 指定多个成功/失败回调函数, 都会调用吗?
- 当 promise 改变为对应状态时都会调用
let p = new Promise((resolve, reject) => { resolve('OK'); }) // 状态为成功,后面的成功的回调函数都会被调用 p.then( val=>{ console.log('成功的回调函数') } ) p.then( val=>{ console.log('成功的回调函数') } ) p.then( val=>{ console.log('成功的回调函数') } )
4.3 改变 promise 状态和指定回调函数谁先谁后
- (1) 都有可能, 正常情况下是先指定回调再改变状态, 但也可以先改状态再指定回调
- (2) 如何先改状态再指定回调?
- ① 在执行器中直接调用 resolve()/reject()
- ② 延迟更长时间才调用 then()
- 看回调函数在执行器中调用的时间
- (3) 什么时候才能得到数据?
- ① 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据
- ② 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据
- 回调函数调用, 得到数据
// 先指定回调函数 // 再改变状态 // 执行器中的执行的为异步任务,调用回调函数在1秒后 let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('OK') }, 1000) }) p.then( (value) => { console.log(value) }, (reason) => {} ) // 先改变状态 // 执行器内为同步任务 // 执行执行器就立马调用成功的回调函数 // 先改变状态在指定回调函数 p = new Promise((resolve, reject) => { resolve('OK') }) p.then( (value) => { console.log(value) }, (reason) => {} )
4.4 promise.then()返回的新 promise 的结果状态
promise.then()返回的新 promise 的结果状态由什么决定?
- (1) 简单表达: 由 then()指定的回调函数执行的结果决定
- (2) 详细表达:
- ① 如果抛出异常, 新 promise 变为 rejected, reason 为抛出的异常
- ② 如果返回的是非 promise 的任意值, 新 promise 变为 resolved, value 为返回的值
- ③ 如果返回的是另一个新 promise, 此 promise 的结果就会成为新 promise 的结果
// 1 let p = new Promise((resolve, reject) => { resolve('ok') }) let res = p.then( (val) => { throw 'err' }, (reason) => {} ) console.log(res) // 2 p = new Promise((resolve, reject) => { resolve('ok') }) res = p.then( (val) => { return 123 }, (reason) => {} ) console.log(res) // 3 p = new Promise((resolve, reject) => { resolve('ok') }) res = p.then( (val) => { return new Promise.reject('Err') }, (reason) => {} ) console.log(res)
4.5 promise 串连多个操作任务(链式调用)
- (1) promise 的 then()返回一个新的 promise, 可以开成 then()的链式调用
- (2) 通过 then 的链式调用串连多个同步/异步任务
let p = new Promise((resolve, reject) => { resolve('ok') }) p.then((val) => { return new Promise((resolve, reject) => { resolve('OK') }) }) .then((val) => { console.log(val) }) .then((val) => { // 上一个then结果集中没有返回值,结果集为undefined // 输出为undefined console.log(val) })
4.6 promise 异常传透
- (1) 当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调,
- (2) 前面任何操作出了异常, 都会传到最后失败的回调中处理
let p = new Promise((resolve, reject) => { resolve('ok') }) p.then( val=>{ throw 'err' } ).then( val=>{ console.log(222); } ).then( val=>{ console.log(222); } ).catch( reason=>{ console.log(reason) } )
出错之后直接到catch,中的其他then不执行
4.7 中断 promise 链
- (1) 当使用 promise 的 then 链式调用时, 在中间中断, 不再调用后面的回调函数
- (2) 办法: 在回调函数中返回一个 pendding 状态的 promise 对象 (有且只有一个方式)
let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('OK'); }, 1000); }); p.then(value => { console.log(111); //有且只有一个方式 // 新创建的Promise对象,且没有调用回调函数,或抛出错误 // 对象的状态没有改变 // 所以该Promise对象的状态为pending // 下面的then,catch定义的为失败或成功的回调函数 // 所以会中断退出,不会继续向下执行 return new Promise(() => {}); }).then(value => { console.log(222); }).then(value => { console.log(333); }).catch(reason => { console.warn(reason); });
5. 自定义手写实现 Promise
5.1 定义整体结构
// 定义Promise的构造函数 function Promise(excutor) { } // 定义Promise的then函数 // 定义在prototype上 Promise.prototype.then = function () { }
官方的 Promise 的实例化对象的 then 等函数都在其原型链上,所以自定义的 Promise 的 then 等函数也挂在原型链上。
5.2 Promise 构造函数的实现
// 定义Promise的构造函数 function Promise(excutor) { // 在执行构造函数时会同步立即执行执行器函数 // 调用传参传过来的执行器函数 // 执行器函数中有两个参数,resolve函数与reject函数 // 执行执行器函数需要传入两个参数,resolve函数与reject函数 excutor(resolve, reject) }
5.2.1 resolve与reject结构搭建
// 定义Promise的构造函数 function Promise(excutor) { // 执行器函数执行过程中会调用resolve或reject函数改变Promise的状态 // resolve与reject函数需要定义 // 定义resolve函数 // 会传递过来一个参数,用于改变Promise的结果值 PromiseResult function resolve(data) { } // 定义reject函数 // 会传递过来一个参数,用于改变Promise的结果值 PromiseResult function reject(data) { } // 调用传参传过来的执行器函数 excutor(resolve, reject) }
5.2.2 resolve与reject函数实现
// 定义Promise的构造函数 function Promise(excutor) { // resolve函数与reject函数改变 Promise的状态 PromiseState 和 Promise的结果 PromiseResult // PromiseState PromiseResult 每个 Promise 对象都有,所以定义在构造函数中 this.PromiseState = 'pending' // 默认状态 pending this.PromiseResult = null // 结果默认为空 // 定义resolve函数 function resolve(data) { // 修改 Promise的状态 PromiseState 为成功 fulfilled/resolved this.PromiseState = 'fulfilled' // 修改 Promise的结果 PromiseResult 为 data this.PromiseResult = data } // 定义reject函数 function reject(data) { // 修改 Promise的状态 PromiseState 为成功 rejected this.PromiseState = 'rejected' // 修改 Promise的结果 PromiseResult 为 data this.PromiseResult = data } // 调用传参传过来的执行器函数 同步调用 excutor(resolve, reject) }
5.2.3 throw抛出错误改变状态
// 定义Promise的构造函数 function Promise(excutor) { // 定义 PromiseState PromiseResult this.PromiseState = 'pending' // 默认状态 pending this.PromiseResult = null // 结果默认为空 // 定义resolve函数 function resolve(data) { this.PromiseState = 'fulfilled' // 修改 Promise的状态 PromiseState this.PromiseResult = data // 修改 Promise的结果 PromiseResult } // 定义reject函数 function reject(data) { this.PromiseState = 'rejected' // 修改 Promise的状态 PromiseState this.PromiseResult = data // 修改 Promise的结果 PromiseResult } // 异常在 excutor 中抛出的 // 捕获 excutor 中的异常并进行处理 try { // 调用传参传过来的执行器函数 同步调用 excutor(resolve, reject) } catch(e) { // 处理异常 // 改变Promise状态为失败,改变结果 // 直接调用 reject 函数 传入失败信息 reject(e) } }
5.2.3 状态只能修改一次
Promise 的状态只能修改一次,只能从 pending 到成功或从 pending 到失败,没有其他可能的改变
// 定义Promise的构造函数 function Promise(excutor) { // 定义 PromiseState PromiseResult this.PromiseState = 'pending' // 默认状态 pending this.PromiseResult = null // 结果默认为空 // 定义resolve函数 function resolve(data) { // 状态只能修改一次 // 如果状态已经修改了(即不为pending)就直接退出 if (this.PromiseState !== 'pending') return; this.PromiseState = 'fulfilled' // 修改 Promise的状态 PromiseState this.PromiseResult = data // 修改 Promise的结果 PromiseResult } // 定义reject函数 function reject(data) { // 状态只能修改一次 // 如果状态已经修改了(即不为pending)就直接退出 if (this.PromiseState !== 'pending') return; this.PromiseState = 'rejected' // 修改 Promise的状态 PromiseState this.PromiseResult = data // 修改 Promise的结果 PromiseResult } // 捕获 excutor 中的异常并进行处理 try { // 调用传参传过来的执行器函数 同步调用 excutor(resolve, reject) } catch (e) { // 处理异常,改变Promise状态为失败,改变结果 reject(e) } }