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)})这两个是谁在前谁先执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Promise是一种用于处理异步操作的机制,它可以将异步操作的结果以同步的方式进行处理和返回。Promise实现原理主要包括以下几个方面: 1. Promise的状态:Promise有三个状态,分别是pending(等待状态)、fulfilled(成功态)和rejected(失败态)。起初,Promise的状态为pending,当异步操作执行完毕后,状态会变为fulfilled或rejected。 2. Promise的构造函数:Promise构造函数内部提供了resolve和reject两个方法。resolve方法用于将Promise的状态修改为fulfilled,同时执行成功回调函数;reject方法用于将Promise的状态修改为rejected,同时执行失败回调函数。一旦状态被修改,就不可逆转。 3. Promise的链式调用:每一个Promise都有一个then方法,then方法返回一个新的Promise对象,这样就可以实现链式调用。通过链式调用,可以实现多个异步操作的顺序执行。 4. Promise的catch方法:catch方法是then方法的一种特殊形式,用于捕获Promise链中的异常,以便进行错误处理。catch方法也支持链式调用。 5. Promise的finally方法:finally方法也是then方法的一种特殊形式,它返回一个新的Promise对象,并在前一个Promise的状态改变后执行。它通常用于无论Promise的状态如何,都需要执行一些最终的操作。 6. Promise的静态方法:Promise还提供了一些静态方法,如Promise.resolve、Promise.reject和Promise.all。Promise.resolve方法返回一个新的Promise对象,并将其状态修改为fulfilled;Promise.reject方法返回一个新的Promise对象,并将其状态修改为rejected;Promise.all方法用于接收一个包含多个Promise的数组,并在所有Promise都成功后返回一个新的Promise对象。 以上是Promise实现原理。通过这种机制,我们可以更方便地处理异步操作,避免了回调地狱的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值