1.macrotask(宏任务)和microtask(微任务)指的是两个队列,脚本的整体代码,setTimeout,setInterval,setImmediate,I/O,回调和UI渲染都会加入到macrotask队列中,process.nextTick回调,Promise(浏览器实现),MutationObserver回调将被添加到微任务队列中。1当浏览器进入事件循环时,先查看macrotask中是否有符合条件执行的任务2如果有,选择一个(只有一个)执行3如果没有,查看是否有任务microtask队列中符合执行条件的4如果是则执行全部(executeall)5更新页面6然后重复上面的行为2.Promise简介Promise的主要作用是保存异步执行结果,以便我们不再使用回调来处理异步任务的结果。我们通过一个回调保存了异步任务的结果,在后面的时间以各种姿势使用。新的romise(执行者).then(函数(结果)}).then(函数(结果){});异步任务,Promise是通过回调实现的,但是它统一了回调,让我们不用再直接接触回调,写异步任务的方式看起来有点像同步,仅此而已,没什么新意,这种同步方式只能是说是类似于同步,下篇文章会讲一个更接近同步,更有建设性的生成器。3.Promise的构造函数应该是这样的functionPromise(excutor){varself=this;varstatus='PENDING';//Promise的当前状态vardata=undefined;//当前执行者(即用户的异步任务)执行结果self.onResolvedCallback=[];//执行器回调函数队列self.onRejectedCallback=[];//Excutor执行失败后回调函数队列functionresolve(value){//TUDO异步任务执行成功Behavior//1改变当前promise的状态值并调用该方法PENDING->RESOLVED//2执行所有回调函数在onResolvedCallback队列并传递异步任务的异步处理结果//onResolvedCallback[i](data)}functionreject(value){//异步任务执行失败后的TUDO行为//1改变当前promise的状态值和callthismethodPENDING->REJECTED//2执行onRejectedCallback队列中的所有回调函数,并传递异步任务的异步处理结果//onRejectedCallback[i](data)}executor(resolve,reject);//执行用户添加的任务}Promise.prototype.then=function(onResolved,onRejected){//onResolved异步任务执行成功的回调//onRejected异步任务执行失败后的回调}具体是这样的用法newPromise(function(resolve,reject){setTimeout(function(result){//resolve(result)orreject(result)取决于返回值//这里我们确实写了一个回调,但是我们并没有在回调中做太多的事件//只是传递了异步处理result想一想,我们这里又要做一个result-dependent//异步任务,回调地狱,代码结构混乱,不易阅读});}).then(function(result){})//这里的result来自上面的在该回调中传递相同的值4.具体实现(1)resolve函数和reject函数functionPromise(excutor){varself=this;varstatus='PENDING';//Promise的当前状态vardata=undefined;//当前执行器(即用户的异步任务)的执行结果self.onResolvedCallback=[];//执行器执行成功后的回调函数队列self.onRejectedCallback=[];//执行器执行失败后的回调函数队列functionresolve(value){//TUDO异步任务执行成功后的行为if(self.status==='PENDING'){self.status='REJECTED';//改变当前promise的状态值,调用这个方法PENDING->RESOLVEDself.data=value;//更新当前数据for(variinself.onResolvedCallback){self.onResolvedCallback[i](self.data);//执行onResolvedCallback队列中的所有回调函数,并通过异步处理异步任务result}}}functionreject(reson){//异步任务执行失败后的TUDO行为if(self.status==='PENDING'){self.status='REJECTED';self.data=共鸣;for(variinself.onRejectedCallback){self.onRejectedCallback[i](self.data);}}}try{executor(resolve.bind(this),reject.bind(this));//执行用户添加的任务/*这里为什么要通过bind进行bind上下文主要是resolve依赖于当前promise的内部属性。在executor函数体中,我们通过resolve(data)或者reject(reson)来调用它。这种方式在非严格模式下调用resolve或reject的上下文是windows,在严格模式下是undefined*/}catch(e){reject.bind(this)(e);//如果发生异常,则通过reject向后传递}}(2)then方法的实现应该有以下功能(1)then方法必须返回一个Promise对象,即由then方法添加的逻辑user必须封装(2)同一个对象可以调用then多次添加逻辑,按照添加的先后顺序执行//例如:varpromise=newPromise(function(resolve,reject){//异步operationandresolveorreject在回调中调用将异步处理结果传递出去});promise.then(function(data){//对异步结果数据进行操作});promise.then(function(data){//对异步结果数据进行操作});//promise是同一个对象(3)可以链接//例如:newPromise(function(resolve,reject){//异步操作,回调中调用resolve或reject传递出异步处理结果}).then(function(data){}).then(function(数据){});这里第一次和第二次调用then的对象是两个不同的对象,这里要注意[1]如果第一个then的参数也是一个Promise,那么在第二个then中会得到处理结果第一个then[2]如果第一个then的参数是一个函数并且有返回值,则第二个then[3]会收到返回值,其他情况会通过newPromise(fn)获取到这里是这个异步fn的处理结果(4)我们写的Promise必须和所有符合Promise规范的Promise一起工作(比如浏览器自带的和第三方库)/***@parmsonResolved当任务successesExecutedcallback*@parmsonRejected任务失败时执行的回调*/Promise.prototype.then=function(onResolved,onRejected){varself=this;变种承诺然后;//then方法返回的promise//如果onResolved或onRejected不是函数我们忽略它,并添加一个传递异步结果的函数onResolved=typeofonResolved==='function'?onResolved:function(value){resolve(value);}onRejected=typeofonRejected==='function'?onRejected:function(reson){resolve(reson);}/*如果调用then时已经执行了异步任务添加依赖异步处理的结果,则使用异步结果执行then中添加的任务*/if(self.status==='RESOLVED'){//这里我们需要将then中要添加的任务包装成一个Promise并返回Promise是针对(3)中的链式调用returnpromiseThen=newPromise(function(resolve,reject){try{//执行then添加的任务varx=onResolved(self.data);if(xinstanceofPromise){/*如果then添加的任务有返回值,返回值是一个Promise对象,让promiseThen接受x的状态和数据值注意这里,promiseThen的resolve和reject是作为then的参数传入的x,这样当promiseThen的resolve和reject会在合适的时候被调用,从而promiseThen接受x的状态和数据值Promise实现不同对象之间的相互影响,通过给其他对象加上自己的resolve和reject*/x.then(resolve,reject);}elseresolve(x);//如果x不是Promise,使用x的值作为promiseThen的结果}catch(e){reject(e);}});}//同上逻辑if(self.status==='REJECTED'){returnpromiseThen=newPromise(function(resolve,reject){try{varx=onReject编辑(自我。数据);if(xinstanceofPromise){x.then(resolve,reject);}}赶上(e){拒绝(e);}});}if(self.status==='PENDING'){//当前Promise的异步任务还没有执行完,则将异步任务包装在then中放入队列中//包装方式同上上面,不同的是上面是立即执行的,这里是放入回调队列returnpromiseThne=newPromise(function(){self.onResolvedCallback.push(function(){try{varx=onResolved(self.data);if(xinstanceofPromise){x.then(resolve,reject);}catch(e){reject(e);}}});self.onRejectedCallback.push(function(){try{varx=onRejected(self.data);if(xinstanceofPromise){x.then(resolve,reject);}catch(e){reject(e);}}});});}}这里Promise实现的功能(1)、(2)、(3)已经完成,也就是说,如果不管和其他Promise的交互,Promise的原理已经解释清楚了。本来打算写一篇的,但是篇幅太长,所以打算分两篇来写。下一篇是generator,后面我会按照规范来做。(4)部分实现。
