/** * 1. A Promise is a class that needs to pass in an executor when it is created. The executor will be executed immediately. This is a big pity and rejected * 3. The two arguments in the executor, resolve, This is a pity * reject which is used to change the status. * Resolve which is pending -> depressing * Reject which is pending -> Rejected * Which can't be changed * 4. The then method takes two parameters of function type, the first parameter is a success callback and the second parameter is a failure callback. If it succeeds, the successful callback will be executed. If it fails, the failed callback will be called. If it fails, the failed callback will be called. Consider the case of an asynchronous API inside the executor * 6. Then methods can be called chained, and subsequent THEN methods succeed with a callback that returns the value of the previous THEN callback * 7. The then method of the same Promise object can be called multiple times and execute */ const PENDING = 'PENDING' in turn; // this is a big pity; // const REJECTED = 'REJECTED '; Class MyPromise{status = PENDING; value = undefined; error = undefined; successCallbacks = []; failCallbacks = []; constructor(executor){ try{ executor(this.resolve, this.reject) }catch(e){ this.reject(e); Resolve = (value)=>{if (this.status === PENDING){this.status == PENDING; this.value = value; / / when the resolve is executed asynchronously, has stored the callback function called while (this) successCallbacks) length) {this. SuccessCallbacks. Shift () (); Reject = (err)=>{if (this.status === PENDING) {this.status = REJECTED; this.error = err; / / when the reject is executed asynchronously, has stored the callback function called while (this) failCallbacks) length) {this. FailCallbacks. Shift () (); }}} then (successCallback, failCallback) {/ / then method parameters optional failCallback = failCallback | | (error = > {throw the error}); // successCallback is not a function, if (! (successCallback instanceof Function)){ successCallback = ()=>this.value } let promise2 = new MyPromise((resolve,reject)=>{if (this.status === depressing) {/*** * if x is a normal value, then resolve will return *. If x is promise2 itself, use setTimeout to execute the code after synchronization. If x is promise2 itself, use setTimeout to execute the code. SetTimeout (() => {try {let x = successCallback(this.value) resolvePromise(promise2, x, resolve) reject); } catch (error) { reject(error) } }); } else if (this.status === REJECTED) { setTimeout(() => { try { let x = failCallback(this.error) resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }); } else {// pending status, This cache callback. SuccessCallbacks. Push ((() = > {setTimeout () = > {try {let x = successCallback (value) this. resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }); }); this.failCallbacks.push(()=>{ setTimeout(() => { try { let x = failCallback(this.error) resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }); }) } }) return promise2; } /** * Whether fail or succeed, */ Finally (callback){return this.then(function(res){// If the callback returns a Promise object, Return myPromise.resolve (callback()).then(()=>res)}, function(err){ return MyPromise.resolve(callback()).then(() => {throw err; })} /** * catch(fun){return this. Then (undefined, fun)} /** * all is a static class method, Static all(arr){const result = []; Return new Promise(function(resolve,reject){return result (resolve,reject); Resolve function addResult(index,res){result[index] = res; resolve function addResult(index,res){result[index] = res; if (result.length === arr.length){ resolve(result); }} arr.map((item,idx)=>{if(item instanceof MyPromise){// If (item instanceof MyPromise){ Then (res => addResult(IDx, res), reject)}else{addResult(idx, item); }})})} /** * Return * if value is a common value, return * if value is a Prmise object, */ static resolve(value){if (value instanceof MyPromise) return value; return new MyPromise(resolve => resolve(value)); } } function resolvePromise(promise2,x,resolve,reject){ if(promise2 === x){ return reject(new TypeError('Chaining cycle detected for promise #<Promise>')) } if(x instanceof MyPromise){ return x.then(resolve,reject) }else{ return resolve(x); }}Copy the code