Let promise1 = new promise ((resolve, reject)=>{setTimeout(() =>{resolve(' resolve ')); }, 2000); }) promise1 .then(res=>{ console.log(res); },err=>{console.log(err); }); // to implement such a function /* note points: */ function MyPromise(exeuctor){self. Status = 'error' 'pending'; self.value = ''; self.reason = ''; Function resolve(data){self.value = data; self.status = 'resolved'; } function reject(reason){self.reason = reason; self.status = 'rejected'; } try {exeuctor(resolve, reject)} catch (err) {reject(err); } } MyPromise.prototype.then = function(onresolve, onrejected){ if(this.status == 'resolved'){ onresolve(self.value); } if(this.status == 'rejected'){ onrejected(self.reason); }} let myPromise1 = new MyPromise((resolve,reject)=>{setTimeout(() =>{resolve(' I ')); }, 2000); }) myPromise1.then((data)=>{ console.log(data); },err=>{ console.log(err); Resolve (' resolve '); resolve(' resolve '); resolve(' resolve ') Resolve (' resolve ') immediately after the then register function? Function MyPromise(exeuctor){let self = this; function MyPromise(exeuctor){let self = this; self.status = 'pending'; self.value = ''; self.reason = ''; + self.resolveCallbacks = []; + self.rejectCallbacks = []; Function resolve(data){self.value = data; self.status = 'resolved'; + self.resolveCallbacks.forEach(func => func(data)); } function reject(reason){self.reason = reason; self.status = 'rejected'; + self.rejectCallbacks.forEach(func => func(reason)); } try {exeuctor(resolve, reject)} catch (err) {reject(err); } } MyPromise.prototype.then = function(onresolve, onrejected){ if(this.status == 'resolved'){ onresolve(this.value); } if(this.status == 'rejected'){ onrejected(this.reason); } + if(this.status == 'pending'){ + this.resolveCallbacks.push(onresolve); + this.rejectCallbacks.push(onrejected); > < span style = "color: # 0000ff00; color: # 0000FF00; color: # 0000FF00; color: # 0000FF00; So when you call THEN you have to return a promise so every time you call THEN you create a promise object and you implement a simple chain call and the idea is that the then function returns a promise and you want to implement a simple chain call Mypromise.prototype. Then = function(onresolve, onRejected){let promise2; Promise2 = new MyPromise((resolve, reject)=>{if(this.status == 'resolved'){ // The code you write is either synchronous or asynchronous. // The code you write is either synchronous or asynchronous. SetTimeout (() => {try {let x = onresolve(self.value); resolvePromise(promise2,x,resolve,reject); } catch (error) { reject(error) } }, 0); } if(this.status == 'rejected'){ setTimeout(() => { try { let x = onrejected(self.reason); resolvePromise(promise2,x,resolve,reject); } catch (error) { reject(error) } }, 0); } the if (this. The status = = 'pending') {this. ResolveCallbacks. Push (() = > {/ / when the first promise state change implement then registered function / / and change the current state of promise Will implement the chain call setTimeout () = > {try {let x = onresolve (self) value) resolvePromise (promise2, x, resolve, reject)} the catch (e) { reject(e) } },0) }); this.rejectCallbacks.push(()=>{ setTimeout(()=>{ try{ let x = onrejected(self.reason) resolvePromise(promise2,x,resolve,reject) }catch(e){ reject(e) } },0) }); }}); return promise2; } let myPromise1 = new MyPromise((resolve,reject)=>{setTimeout(() =>{resolve(' I ')); }, 2000); }) myPromise1 .then((data)=>{ console.log(data+'1'); },err=>{ console.log(err); }) .then((data)=>{ console.log(data+'2'); },err=>{ console.log(err); }) .then((data)=>{ console.log(data+'3'); },err=>{ console.log(err); })Copy the code
// Print li4 1 Li4 2 Li4 3
Implement a complex chain call when let x = onresolve(this.value); If x is a promise then you need a function to determine if x is a promise
if(promise2 === x){ return reject(new TypeError('Chaining cycle detected for promise')) } let called if(x ! == null && (typeof x === 'object' || typeof x === 'function')){ try{ let then = x.then if(typeof then === 'function'){ Then. Call (x,(y)=>{// if(called) return called = true // promise2 resolve reject resolvePromise(promise2,y,resolve,reject) },(err)=>{ if(called) return called = true reject(err) }) }else{ resolve(x) } } Catch (e){if(called) return called = true reject(e)}}else{// Make a promise when the then registered function returns a constant resolve(x) } }Copy the code
The hardest thing for me to understand is that resolvePormise does what it does when it returns a promise and registers the then function if it returns a promise, and uses the resolvePormise process so it handles the whole chain call
Complete code, while testing
function MyPromise(exeuctor){ let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.resolveCallbacks = []; self.rejectCallbacks = []; Function resolve(data){if(self.status == 'pending'){self.value = data; self.status = 'resolved'; self.resolveCallbacks.forEach(func => func()); Function reject(reason){if(self.status == 'pending'){self.reason = reason; self.status = 'rejected'; self.rejectCallbacks.forEach(func => func()); }} try {exeuctor(resolve, reject)} catch (err) {reject(err); } } function resolvePromise(promise2,x,resolve,reject){ if(promise2 === x){ return reject(new TypeError('Chaining cycle')); } let called; // prevent state from changing more than once if(x! ==null&&(typeof x === 'object' || typeof x === 'function')){ try { let then = x.then; Call (x,y => {if(called) return; if(typeof then === 'function'){// x = promise then. Call (x,y => {if(called) return; called = true; resolvePromise(promise2,y,resolve,reject); },err=>{ if(called) return; called = true; reject(err) }) } else { resolve(x); } } catch (err) { if(called) return; called = true; reject(err); }} else {/* Resolve (x) if x is a constant; } } MyPromise.prototype.then = function(onresolve, onrejected){ let promise2; let self = this; onresolve = typeof onresolve === 'function'? onresolve:val=>val; onrejected = typeof onrejected === 'function'? onrejected: err=>{throw err} promise2 = new MyPromise((resolve, reject)=>{ if(self.status === 'resolved'){ setTimeout(() => { try { let x = onresolve(self.value); resolvePromise(promise2,x,resolve,reject); } catch (error) { reject(error) } }, 0); } if(self.status === 'rejected'){ setTimeout(() => { try { let x = onrejected(self.reason); resolvePromise(promise2,x,resolve,reject); } catch (error) { reject(error) } }, 0); } the if (self status = = = 'pending') {self. ResolveCallbacks. Push (() = > {/ / with 13 setTimeout (() = > {try {let x = onresolve(self.value) resolvePromise(promise2,x,resolve,reject) }catch(e){ reject(e) } },0) }) Self. RejectCallbacks. Push (() = > {/ / with 13 setTimeout (() = > {try {let x = onrejected (self. "reason) resolvePromise(promise2,x,resolve,reject) }catch(e){ reject(e) } },0) }) } }); return promise2; } MyPromise.defer = MyPromise.deferred = function(){ let dfd = {}; dfd.promise = new MyPromise((resolve,reject)=>{ dfd.resolve = resolve; dfd.reject = reject; }) return dfd; } module.exports = MyPromise;Copy the code
Promises – aplus-test-g NPM install Promises – aplus-test-g
I am happy to write a myPromise that complies with the promiseA+ specification. I recommend reading this article as well. I’m going to implement two functions race and all and I’m sure you all know what these two functions do
MyPromise.race = function(promises){ return new MyPromise((resolve, reject)=>{ promises.forEach(item=>{ item.then(resolve,reject); RaceRes = mypromise.race ([new MyPromise(resolve,reject)=>{setTimeout(() =>{resolve(2000)}, 2000) }), new MyPromise((resolve,reject)=>{ setTimeout(() => { resolve(5000) }, 5000) }) ]) .then(res=>{ console.log(res); // 2000 },err=>{ console.log(err); }) ----------------all----------------- MyPromise.all = function(promises){ return new MyPromise((resolve, reject)=>{ let resArr = []; let i = 0; function processData(key,res){ resArr[key] = res; if(++i === promises.length){ resolve(resArr) } } promises.forEach((item,key)=>{ item.then(res=>{ processData(key,res); },err=>reject(err)) }) }) }; MyPromise.all([ new MyPromise((resolve,reject)=>{ setTimeout(() => { resolve(2000) }, 2000) }), new MyPromise((resolve,reject)=>{ setTimeout(() => { resolve(5000) }, 5000) }) ]) .then(res=>{ console.log('all',res); // all (2) [2000, 5000] },err=>{ console.log(err); })Copy the code
I highly recommend reading xiao Shao to teach you to play promise source code
Record what you have learned, the level is limited inevitable mistakes, welcome to point out ~~