一篇学完Promise和查阅了许多资料和历史后留的笔记
先上概念
Promise是一个对象
Promise是ES6提出的一个异步解决方案,这个方案主要是解决了以前异步问题的困境。
Promise本身是一个同步代码,但是他的then方法等是异步代码,这些异步代码都是属于微队列的,会比宏队列的任务优先级更高
这里存在几个小点,在ES6之前 js是怎么异步问题的?解决了怎么样的异步的问题?
在ES6之前 JS主要依靠回调函数解决异步问题,但是因此引出了第二个问题,大量的异步回调会产生“回调地狱”,在大量回调的中不仅让代码非常不优雅,而且在其中一个环节如果出现错误,就会导致后面的回调纷纷不能执行
在ES6的时候才真正出现了官方解决回调的的问题,功能十分强大,可以链式调用,避免了环环嵌套
注意事项
Promise的状态一旦更改,除了一些特殊情况(例如在then中又调用了Promise对象,那就会以新的Promise对象的状态为主) 状态有3个状态:
1.fulfilled(实现),
2.rejected(拒绝),
3.pending(发送中)
// 前两个都是过去式代表已经发生,最后一个是现在进行时代表正在进行,
实例方法
then()
then可以传入2个回调函数resolve,reject,传入参数这些状态是可选的,注意then返回的是一个promise对象,可以进行链式调用
catch()
catch可以捕获rejected状态返回的参数,可以说是then第二个回调的分离
finally()
无论是什么成功或失败,都会返回一个结果
静态方法
all([])
传入一组请求(或一个普通参数),当里面所有内容为fulfiled状态时才回返回这组Promise对象的集合,如果出现一个rejected状态就返回为第一个对象 。 // 普通参数都作为fulfilled状态处理
race([])
竞赛
一组请求中返回第一个完成的请求
Promise源码
class testPromise{
static pending = 'pending'
static fulfilled = 'fulfilled'
static rejected = 'rejected'
status = null
result = null
resTick = []
rejTick = []
constructor(callback){
// resolve 函数
let resolve = (values)=>{
this.status = testPromise.pending
this.result = values
this.resTick.forEach(i =>{
i()
})
}
// reject 函数
let reject = (reason)=>{
this.status = testPromise.rejected
this.result = reason
}
try {
callback(resolve,reject)
} catch (error) {
reject(error)
}
}
// then方法
resolvePromise(x,resolve,reject){
if (x instanceof testPromise) { // 判断传来的值是不是Promise对象
x.then(res =>{
resolve(res)
}) // 如果是 就可以调用他的then的值 形成链式调用
x.catch(res=>{
reject(res)
})
}else{ // 如果不是直接返回该值
resolve(x)
}
}
then(res,err){
// then 链式调用 返回一个promise对象
const thenPromise = new testPromise((resolve,reject)=>{
if (this.status === testPromise.fulfilled) {
let x = res(this.result)
this.resolvePromise(x,resolve,reject) // 将值返回给下一个then
}else if(this.status === testPromise.rejected){
let x = err(this.result)
this.resolvePromise(x,resolve,reject) // 将值返回给下一个then
}
else if(this.status === testPromise.pending) {
this.resTick.push(()=>{
let x = res(this.result)
this.resolvePromise(x,resolve,rejuct)
})
this.rejTick.push(()=>{
let y = err(this.result)
this.resolvePromise(y,resolve,rejuct)
})
}
})
return thenPromise
}
catch(res){
if (this.status === testPromise.rejected) {
let x = res(this.result)
this.resolvePromise(x,resolve,reject) // 将值返回给下一个then
} else if(this.status === testPromise.pending) {
this.rejTick.push(()=>{
let x = res(this.result)
this.resolvePromise(x,resolve,reject)
})
}
}
static resolve(res){
return new testPromise((resolve,reject)=>{
resolve(res)
})
}
static reject(reason){
return new testPromise((resolve,reject)=>{
reject(reason)
})
}
static all(arr){
const allResult = []
let count = 0
return new testPromise((resolve,reject)=>{
const addData = (index,item)=>{
allResult[index] = item
count++
if (count === arr.length)resolve(allResult)
}
arr.forEach((item,index)=>{
if (item instanceof testPromise) {
item.then(res=>{
addData(index,res)
},err=>{
reject(err)
})
}else{
addData(index,item)
}
})
})
// 参数不一定非得是数组
// p的状态由p1、p2、p3决定,分成两种情况。
// (1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
// (2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
}
static race(arr){
// console.log(123);
// return new testPromise((resolve,reject)=>{
// for (let i = 0; i < arr.length; i++) {
// console.log(arr[i]);
// arr[i].then(resolve,reject)
// }
// })
return new testPromise((resolve,reject)=>{
arr.forEach((i)=>{
if (i instanceof testPromise) {
i.then(resolve,reject)
}else{
reject(i)
}
})
})
}
}