You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// three statesconstPENGING='pending';constRESOLVED='resolved';constREJECTED='rejected';// promise accepts a function argument that will execute immediately.functionMyPromise(fn){const_this=this;_this.currentState=PENDING;// the value of Promise_this.value=undefined;// To save the callback of `then`,only cached when the state of the promise is pending,// for the new instance returned by `then`, at most one will be cached_this.resolvedCallbacks=[];_this.rejectedCallbacks=[];_this.resolve=(value)=>{if(valueinstanceofMyPromise)// If value is a Promise, execute recursivelyreturnvalue.then(_this.resolve,_this.reject)}// execute asynchronously to guarantee the execution ordersetTimeout(()=>{if(_this.currentState===PENDING){_this.currentState=RESOLVED;_this.value=value;_this.resolvedCallbacks.forEach(cb=>cb());}})}_this.reject=(reason)=>{setTimeout(()=>{if(_this.currentState===PENGING){_this.currentState=REJECTED;_this.value=reason;_this.rejectedCallbacks.forEach(cb=>cb());}})}// to solve the following problem// new Promise(() => throw Error('error))try{fn(_this.resolve,_this.reject);}catch(e){_this.reject(e);}}MyPromise.prototype.then=function(onResolved,onRejected){constself=this;// specification 2.2.7, `then` must return a new promiseletpromise2;// specification 2.2, both `onResolved` and `onRejected` are optional arguments// it should be ignored if `onResolved` or `onRjected` is not a function, which implements the penetrate pass of it's value// Promise.resolve(4).then().then((value) => console.log(value))onResolved=typeofonResolved==='function' ? onResolved : v=>v;onRejected=typeofonRejected==='function' ? onRejected : r=>throwr;if(self.currentState===RESOLVED){return(promise2=newMyPromise((resolve,reject)=>{// specification 2.2.4, wrap them with `setTimeout`, in order to insure that `onFulfilled` and `onRjected` execute asynchronously, setTimeout(()=>{try{letx=onResolved(self.value);resolutionProcedure(promise2,x,resolve,reject);}catch(reason){reject(reason);}});}));}if(self.currentState===REJECTED){return(promise2=newMyPromise((resolve,reject)=>{// execute `onRejected` asynchronouslysetTimeout(()=>{try{letx=onRejected(self.value);resolutionProcedure(promise2,x,resolve,reject);}catch(reason){reject(reason);}});}))}if(self.currentState===PENDING){return(promise2=newMyPromise((resolve,reject)=>{self.resolvedCallbacks.push(()=>{// Considering that it may throw error, wrap them with `try/catch`try{letx=onResolved(self.value);resolutionProcedure(promise2,x,resolve,reject);}catch(r){reject(r);}});self.rejectedCallbacks.push(()=>{try{letx=onRejected(self.value);resolutionProcedure(promise2,x,resolve,reject);}catch(r){reject(r);}})}))}}// specification 2.3functionresolutionProcedure(promise2,x,resolve,reject){// specification 2.3.1,`x` and `promise2` can't refer to the same object, avoiding the circular referencesif(promise2===x){returnreject(newTypeError('Error'));}// specification 2.3.2, if `x` is a Promise and the state is `pending`, the promise must remain, If not, it should execute. if(xinstanceofMyPromise){if(x.currentState===PENDING){// call the function `resolutionProcedure` again to confirm the type of the argument that x resolves// If it's a primitive type, it will be resolved again to pass the value to next `then`.x.then((value)=>{resolutionProcedure(promise2,value,resolve,reject);},reject)}else{x.then(resolve,reject);}return;}// specification 2.3.3.3.3 // if both `reject` and `resolve` are executed, the first successful execution takes precedence, and any further executions are ignoredletcalled=false;// specification 2.3.3, determine whether `x` is an object or a functionif(x!==null&&(typeofx==='object'||typeofx==='function')){// specification 2.3.3.2, if can't get `then`, execute the `reject`try{// specification 2.3.3.1letthen=x.then;// if `then` is a function, call the `x.then`if(typeofthen==='function'){// specification 2.3.3.3then.call(x,y=>{if(called)return;called=true;// specification 2.3.3.3.1resolutionProcedure(promise2,y,resolve,reject);},e=>{if(called)return;called=true;reject(e);});}else{// specification 2.3.3.4resolve(x);}}catch(e){if(called)return;called=true;reject(e);}}else{// specification 2.3.4, `x` belongs to primitive data typeresolve(x);}}
The text was updated successfully, but these errors were encountered:
Promises/A+
整篇promise的实现不是我原创,是我研究了群里某位大佬以及一些前人的实现,在自己理解的基础上,记录下来,本篇文章更多是为自己服务
注释我写成英文了(具体缘由暂时不说了)
相信有能力理解promise的程序员都有阅读英文的能力(暂时没有也建议掌握这项能力)
The text was updated successfully, but these errors were encountered: