Promise以及promise all的特性和实现

155 阅读2分钟

一、promise特性

  1. 参数是个立即执行函数,该函数接受两个函数参数,分别是resolve,reject,resolve,reject函数参数去哪了?:::分别作为第一个then两个对应回调的参数了

  2. promise状态变更:执行resolve ---->fulfilled; 执行reject ---> 变更为rejected; 状态一经更改,不可再变。

  3. then中的两个回调函数,分别对应fulfilled,rejected状态。即fulfilled执行第一个回调,rejected执行第二个回调。

  4. ***!!! then中两个回调函数返回值谁来接收?答:当然是新promise对象的两个回调函数。

  5. then中返回promise实例(new promise(resolve,reject))

  6. ***!!! resolve有延时,怎么处理? a.then的promise状态加setTimeout,0变成宏任务 b.在resolve和reject中while判断,shift执行

  7. promise all:

    a. all的参数是数组,参数类型可以是promise对象也可以是普通值

    b. all的返回值是promise实例

    c. 只有参数列表中所有状态都成功时,该promise状态才是fulfilled状态。若有一个参数状态为失败状态,则该promise状态未rejected。(参数列表中类型为普通值,返回其普通值,类型为promise,执行promise拿到其状态)


二、promise目标

new Promise((resolve,reject)=>{
  //setTimeout(()=>{
    resolve()
  //},2000)
})
.then((res)=>{
   console.log(1)
})
.then((res)=>{
  console.log(2)
})
.then((res)=>{
  console.log(3)
})

了解promise特性后,实现目标二的promise就显得容易了。


三、promise实现

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
class Promise{
	status = PENDING
    sucCallBack = []
	constructor(exc){
    	try{
        	exc(this.resolve)
        }catch(e){
        	console.log(e)
        }
    }
    resolve =()=>{
    	if(this.status != PENDING){
        	return
        }
        this.status = FULFILLED
        while(this.sucCallBack.length){
        	this.sucCallBack.shift()()
        }
    }
    then = (sucRes)=>{
    	let result = new Promise((resolve)=>{
        	if(this.status == FULFILLED){
            	setTimeout(()=>{
                	let thenRes = sucRes()
                    resolve(thenRes)
                },0)
            }else{
            	//如果promise的resolve有延时,then执行时promise状态未变更。所以就将then中的执行保存到sucCallBack,当resolve时,去sucCallBack中调用。
            	this.sucCallBack.push(()=>{
                	setTimeout(()=>{
                      let thenRes = sucRes()
                      resolve(thenRes)
                  },0)
                })
            }
        })
        return result
    }
}

四、promise all实现代码片段

static all(arr){
	let result = []
    let count = 0//很重要 存在的意义:防止参数有异步状态,用count来进行校验对比
    return new Promise(resolve,reject){
    	function addData(key,val){
        	result[key]=val
            count++
            if(count == arr.length){
            	resolve(result)
            }
        }
    	for(let i =0,len = arr.length;i<len;i++){
        	const ele = arr[i]
            if(ele instanceof Promise){
            	ele.then(suc=>addData(i,suc),fail=>reject(fail))
            }else{
            	addData(i,ele)
            }
        }
    }
}

let p1 = new Promise((resolve, reject) => {
  resolve(1)
})
let p2 = new Promise((resolve, reject) => {
  resolve(2)
})
let p3 = new Promise((resolve, reject) => {
  resolve(3)
})
let pt = Promise.all([p1, p2, p3]).then((res) => {
  console.log(res)
})