Promise内部实现

resolve1(arg){

  if(arg.tyeof === promise){

    weirenwu(()=>{
    
      arg.then(()=>{ //该箭头函数为then方法的参数,即回调函数,调用参数arg的then方法,arg为promise,then方法内部处理机制按照then方法内部源码进行处理
      
        resolve1()//then方法中会执行外层promise的resolve1方法,而不是arg中的promise的resolve方法,相当于递归。
        //从而改变外层promise的状态,同时如果有_fulfilledQueues的话还会在微任务中执行_fulfilledQueues中的回调函数
        
       })

       },0)

      return

   }

  status = 1//如果参数不是promies,那么会先将外层promise的状态设置为1,即resolve状态,然后再判断有没有_fulfilledQueues,例子1可以证明

  if(_fulfilledQueues){ //如果参数不是promise,那么判断是否存有then方法的回调函数

    weirenwu(()=>{

    //遍历_fulfilledQueues,并执行_fulfilledQueues中储存的then方法的回调函数

     },0)

   }

 }
 
then1(){
        return new Promise( (resolve1)=>{
            if(pending){ //父级promise即调用then方法的那个promise的状态是pending的话
                //把then方法中的回调函数(记做cb1)放入到_fulfilledQueues
                //then方法返回的这个new Promies的状态是由cb1执行的时候改变的,resolve1会作为参数传递给cb1,只有在cb1执行的时候才会调用resolve1,才会将then方法返回的这个new Promies的状态由pending状态改为resolve
                //从resolve方法中我们可以分析到只有在执行微任务的时候才会进行 _fulfilledQueues的遍历以及存在于_fulfilledQueues中的cb1的执行
                //所以此时在执行宏任务中遇到的then方法,其状态是pending
            }else{
                weirenwu(()=>{
                    //执行then方法中传递的回调函数,微任务执行的时候才会改变return的promise的状态
                },0)
            }
        } )
        //通过上述分析可以知道,在宏任务中调用then方法时,then方法返回的promise都是pending状态,这保证 了then后继续链式调用then时,后一个then中的回调函数不会立马执行,会先放入到前一个then返回的promise的_fulfilledQueues中,
        //只能等前边的then返回的promise执行了resolve之后(resolve的时候会判断是否有_fulfilledQueues,有的话再放入微任务中执行),才会执行后边then中的回调函数。
}

 例子1:
 let a = new Promise((resolve)=>{
		setTimeout(()=>{
			new Promise((resolve)=>{
				resolve()
			}).then(()=>{console.log('a',a)})//resolve
			resolve()
      console.log('c',a)//resolve
		},0)	
	}) 
	console.log('p',a)//pending
	a.then(()=>{console.log(1111,a)})//resolve
  ==========================================
  结论:
 resolve接收promise作为参数时,通过arg.then可看出只有参数promose的状态改变为完成时,才会去调用then中的回调函数,该回调函数中才会去执行外层promise的resolve方法,从而来改变外层promise的状态,同时如果外层promise中有_fulfilledQueues(注释1)的话,会放入微任务中执行遍历_fulfilledQueues执行其中储存的回调函数。
如此从内往外一层层执行,只有内部的promise状态改变才会去触发外部promise的状态改变,当内部promise状态没有改变时,外部的promise状态也不会改变。
注释1:
_fulfilledQueues内部存的是外层promise为pending时将then中的回调函数(由于执行resolve时会先 status=1,后判断有没有_fulfilledQueues,如果有的话又是在下一个微任务中执行,所以执行_fulfilledQueues中的回调函数时,打印出的外层的promise的状态已经是resolve的)
_fulfilledQueues中存储的回调函数 不仅有我们自己在代码中通过这种promise.then(()=>{})写法写的then中的箭头函数,而且也可能有内部代码中的arg.then(()=>{})中的箭头函数,如下例2:promise2内部接收一个promose1作为resolve的参数,同时又作为了外层promise3的resolve的参数,第一次执行script标签整体代码时即第一个宏任务时,promise2肯定是pending状态,
那么执行resolve3()执行的时候,通过resolve内部代码实现看到arg.then(()=>{})这段代码中的arg是promise2,promise2又是pending状态,那么就会把arg.then(()=>{})中的箭头函数放入到promise2的_fulfilledQueues中,这也能够保证当promise2的resolve被执行的时候,先是把promise2的状态设置为1,
然后_fulfilledQueues中有arg.then(()=>{})中的箭头函数,所以会放在微任务队列中在微任务队列中执行该箭头函数,我们知道该箭头函数中存放的是resolve3(),所以执行resolve3时改变promise3的状态和执行promise3的_fulfilledQueues。_fulfilledQueues中存放arg.then(()=>{})中的箭头函数这一做法 保证了里层promise执行resolve的时候能够通过执行_fulfilledQueues中存放的arg.then(()=>{})中的箭头函数来触发外层promise的resolve。
例子2:let a = new Promise3((resolve3)=>{resolve3(
    	new Promise2((resolve2)=>{resolve2(
    		new Promise1((resolve1)=>{resolve1(
    		)})
    	)})
    )})
    a.then(()=>{console.log(777,a)})
  
例子3:
promise11: new Promise((resolve4)=>{resolve4(
    	new Promise((resolve3)=>{resolve3(
    		new Promise((resolve2)=>{resolve2(
    			new Promise((resolve1)=>{resolve1(
    				new Promise((resolve)=>{resolve()})
    			)})
    		)}).then(()=>{console.log(1)})
    	)})
    )})
	
  promise22: new Promise((resolve4)=>{resolve4(
    	new Promise((resolve3)=>{resolve3(
    		new Promise((resolve2)=>{resolve2(
    			new Promise((resolve1)=>{resolve1(
    				new Promise((resolve)=>{resolve()})
    			)}).then(()=>{console.log(2)})
    		)})
    	)})
    )})
 执行顺序2,1
 根据以上原理可以知道嵌套的promise是由内往外执行从而改变外层promise的状态的,两个层层嵌套的promise比较顺序时, script第一次宏任务时会找出两个promise中的微任务放入微任务队列,执行微任务时,每执行一次微任务会产生一个新的微任务,将新的微任务放入到微任务队列的尾部,
 所以两个嵌套的promise,谁的then方法嵌套的越靠里谁就会先执行,如果两个then位置一样,那就看这两个的promise(promise11与promise22)在同步代码中的位置,谁在谁就先执行,因为谁在前谁就会先放入到微任务队列。

Promise.resolve()中接收一个Promise作为参数时会立马原封不动的返回该Promise,会立马返回,不会再在微任务中返回该Promise,所以Promise.resolve().then(()=>{console.log(1)})与new Promise(()=>{resolve()}).then(()=>{console.log(2)})这两个是谁在前谁先执行

你可能感兴趣的:(Promise内部实现)