理解实现之前最好先了解promise的使用。如果没有,您可以先查看相关文件。另外,你还需要了解事件循环,了解宏任务和微任务。这个Promise的实现只考虑了resolve,reject的思路和resolve差不多,所以不参与增加读取成本。//使用示例:newPromise1(exec).then(fullfill).then(fullfill2)functionexec(resolve){console.log(1)setTimeout(()=>{resolve(1)},3000)}functionfullfill(val){console.log(val,1)returnnewPromise1((resolve)=>{setTimeout(()=>{resolve(2)},3000)})}functionfullfill2(val){console.log(val,2)}我们先不考虑内部做了什么。根据例子我们可以知道,Promise然后接收到两个外部函数,分别是exec和fullfill,resolve,然后一定是在结构体内部,所以可以大致介绍一个Promise结构体functionPromise1(){functionresolve(){}this.then=function(){}}在使用Promise的时候可以发现通过Promise接收到的exec函数在使用过程中是同步执行的,exec接收到的是resolve函数,另外一个fullfill接受一个val参数和自己asthen的一个参数,所以可以进一步得到下面的情况promise过程,首先执行内部的exec函数并将resolve作为参数传入,然后通过resolve函数触发then函数传入的fullfill。可以发现,执行then函数时,先存储传入的fullfill函数,然后在触发resolve时,取出存储的fullfill函数执行。这时候传入resolve函数的val参数也可以传给fullfilledFunc使用。所以我们需要一个数组来保存执行then时的fullfill函数,在resolve中调用,如下fullfilledFunc(val)})}this.then=function(fullfill){fullfillStack.push(fullfill)}exec(resolve)}上面的代码显然是同步执行的,但是resolve只能在then函数之后调用,否则可能会有在执行resolve的fullfillStack中没有任何内容。所以我们需要一个定时器来达到异步延时的效果。functionPromise1(exec){letfullfillStack=[]functionresolve(val){setTimeOut(()=>{fullfillStack.forEach((fullfill)=>{fullfill(val)})},0)}this.then=function(fullfill){fullfillStack.push(fullfill)}exec(resolve)}我们知道Promise是添加了微任务的。NativePromise在浏览器中是通过MutationObserveAPI实现的,在Node中是通过process.nextTick来实现的,我们先用Node(因为简单哈哈),浏览器版本在最后。functionPromise1(exec){letfullfillStack=[]functionresolve(val){process.nextTick(()=>{fullfillStack.forEach((fullfill)=>{fullfill(val)})})}this.then=function(fullfill){fullfillStack.push(fullfill)}exec(resolve)}我们知道then执行后返回的是一个promise,我们可以像例子中那样使用调用链方式。这时候就需要用状态来保证结果了。处理和调用链的实现见下文:fullfilled'data=valfullfillStack.forEach((fullfill)=>{fullfill(data)})})}this.then=function(fullfill){if(state==='pending'){fullfillStack.push(fullfill)returnthis}elseif(state==='fullfilled'){fullfill(data)}}exec(resolve)}但是这样你会发现例子中的结果是:1112第二个then中的val是仍然在firstthenval中,这是因为每次都返回promise本身而不是新的promise。其实这两者应该没有什么关系,所以我们应该返回一个新的promise函数Promise1(exec){letfullfillStack=[]letstate='pending'letdata=nullfunctionresolve(val){process.nextTick(()=>{state='fullfilled'data=valfullfillStack.forEach((fullfill)=>{fullfill(data)})})}this.then=function(fullfill){returnnewPromise1(resolve=>{functionsuccess(){//判断传入的fullfill并处理数据letresult=typeoffullfill==='function'?fullfill(data):data//判断结果是否为promiseif(resultinstanceofPromise1&&typeofresult['then']==='function'){result.then(function(val){resolve(val)})}else{resolve(result)}}if(state==='pending'){fullfillStack.push(success)}elseif(state==='fullfilled'){success(data)}})}exec(resolve)}因为我们要返回一个新的promise,所以直接在then函数中生成一个Promise实例,需要判断then函数接收到的参数,所以我们用一个函数来封装这些过程如果是函数,我们可以让它处理resolve传过来的值。我们还需要处理处理后的结果,因为结果可能是一个承诺。其他地方和上一步基本一样。请注意,当状态为pending时,应该推送success而不是原来的fullfill。至此,诺言基本兑现。浏览器版本实现:functionresolve(val){//makemicroRequestletcallback=function(){fullfilledStack.forEach((fullfilledFn)=>{fullfilledFn(val)})letchild=document.createElement('div')letconfig={childList:true}letobserver=newMutationObserver(callback)observer.observe(targetNode,config)lettargetNode=document.createElement('div')functiontriggerCallback(targetNode,child){targetNode.children.length>0?targetNode.removechild(child):targetNode.appendChild(child)}triggerCallback(targetNode,child)}
