理解Promise (4)
then 方法必須?返回一個(gè)新的promise
promise2 = promise1.then(onFulfilled, onRejected);新的Promise 必須返回傳遞兩個(gè)方法? onFulfilled, onRejected
If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).onFulfilled, onRejected? 其中的某個(gè)都要返回 一個(gè)value
if either?onFulfilled?or?onRejected?returns a value?x, run the Promise Resolution Procedure?[[Resolve]](promise2, x)
如果onfulled或onrejected返回值x,請(qǐng)運(yùn)行承諾解決過(guò)程[[解決]](promise2,x)。
let x = onfulfilled(this.value);// x是普通值還是promise 如果是普通值 直接調(diào)用promise2的resolve// 如果是promise 那應(yīng)該讓x這個(gè)promise執(zhí)行 x.thenresolvePromise(promise2,x,resolve,reject);這段代碼是??resolvePromise? ??承諾解決過(guò)程
resolvePromise? 這個(gè)函數(shù)里面 有Promise 這個(gè)參數(shù),所以我們要拿到這個(gè)值 但是我們直接打印出來(lái)這個(gè)值 是 underfind 所以我們要用?promise2
這樣,我們做到這里的時(shí)候? then 方法的大概結(jié)構(gòu)就出來(lái)了?
then(onfulfilled,onrejected){ let promise2;promise2 = new Promise((resolve,reject)=>{if(this.status === 'fulfilled'){setTimeout(()=>{ try{let x = onfulfilled(this.value);// x是普通值還是promise 如果是普通值 直接調(diào)用promise2的resolve// 如果是promise 那應(yīng)該讓x這個(gè)promise執(zhí)行 x.then resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0);}if(this.status === 'rejected'){setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)}if(this.status === 'pending'){this.resolveCallbacks.push(()=>{setTimeout(()=>{try{let x = onfulfilled(this.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)});this.rejectCallbacks.push(()=>{setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)})}});return promise2}接下來(lái)我們來(lái)處理? ?The Promise Resolution Procedure? 的問(wèn)題?
If?promise?and?x?refer to the same object, reject?promise?with a?TypeError?as the reason.
let resolvePromise = (promise2,x,resolve,reject) => {if(promise2 === x){return reject(new TypeError('循環(huán)引用'))} }?if?x?is an object or function,
if(typeof x === 'function' || (typeof x === 'object' && x !== null)){}Let?then?be?x.then
let then = x.then; // 如果取then方法出錯(cuò) 那就用錯(cuò)誤拒絕promise2? ? ? ?
if(typeof then === 'function'){ // 我就認(rèn)為他是一個(gè)promisethen.call(x,y=>{ // 讓當(dāng)前的promise執(zhí)行 ,不用多次取then方法了// y 有可能還是一個(gè)promise , 繼續(xù)調(diào)用resolvePromise方法,直到解析出一個(gè)常量為止,最終把常量傳遞下去if(called) return; // 放置此方法多次被調(diào)用called = true;resolvePromise(promise2,y,resolve,reject);},r=>{if(called) return;called = true;reject(r); // 讓當(dāng)前的promise變成失敗態(tài)即可 })}else{// x就是一個(gè)普通的對(duì)象 并沒(méi)有then方法 resolve(x);}全部的代碼:
?
let resolvePromise = (promise2,x,resolve,reject) => {// 判斷x的類型 來(lái)處理promise2是成功還是失敗// 所有的promise都遵循這個(gè)規(guī)范,不同的人寫的promise可能會(huì)混用// 盡可能考慮的周全 要考慮別人promise可能出錯(cuò)的情況if(promise2 === x){return reject(new TypeError('循環(huán)引用'))}// 判斷x是不是一個(gè)promise ,這個(gè)x 可能不是自己的promise 所以為了安全 需要在進(jìn)行校驗(yàn),放置調(diào)一起用成功和失敗 if(typeof x === 'function' || (typeof x === 'object' && x !== null)){// 嘗試取當(dāng)前x的then方法, 這個(gè)then方法可能別人定義的時(shí)候 用的Object.defineProperty let called;try{let then = x.then; // 如果取then方法出錯(cuò) 那就用錯(cuò)誤拒絕promise2if(typeof then === 'function'){ // 我就認(rèn)為他是一個(gè)promisethen.call(x,y=>{ // 讓當(dāng)前的promise執(zhí)行 ,不用多次取then方法了// y 有可能還是一個(gè)promise , 繼續(xù)調(diào)用resolvePromise方法,直到解析出一個(gè)常量為止,最終把常量傳遞下去if(called) return; // 放置此方法多次被調(diào)用called = true;resolvePromise(promise2,y,resolve,reject);},r=>{if(called) return;called = true;reject(r); // 讓當(dāng)前的promise變成失敗態(tài)即可 })}else{// x就是一個(gè)普通的對(duì)象 并沒(méi)有then方法 resolve(x);}}catch(e){if(called) return;called = true;reject(e);}}else{// x肯定一個(gè)常量 resolve(x);} }class Promise{constructor(executor){this.status = 'pending'; this.value; this.reason;this.resolveCallbacks = []; // 當(dāng)then是pending 我希望吧成功的方法都放到數(shù)組中this.rejectCallbacks = [];let resolve = (value)=>{if(this.status == 'pending'){this.status = 'fulfilled';this.value = value;this.resolveCallbacks.forEach(fn=>fn()); // 發(fā)布 }}let reject = (reason)=>{if(this.status === 'pending'){this.status = 'rejected';this.reason = reason;this.rejectCallbacks.forEach(fn=>fn())}}try{executor(resolve,reject);}catch(e){reject(e);}}then(onfulfilled,onrejected){ let promise2;promise2 = new Promise((resolve,reject)=>{if(this.status === 'fulfilled'){setTimeout(()=>{ try{let x = onfulfilled(this.value);// x是普通值還是promise 如果是普通值 直接調(diào)用promise2的resolve// 如果是promise 那應(yīng)該讓x這個(gè)promise執(zhí)行 x.then resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0);}if(this.status === 'rejected'){setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)}if(this.status === 'pending'){this.resolveCallbacks.push(()=>{setTimeout(()=>{try{let x = onfulfilled(this.value);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)});this.rejectCallbacks.push(()=>{setTimeout(()=>{try{let x = onrejected(this.reason);resolvePromise(promise2,x,resolve,reject);}catch(e){reject(e);}},0)})}});return promise2} } module.exports = Promise;?
?
https://promisesaplus.com/
轉(zhuǎn)載于:https://www.cnblogs.com/guangzhou11/p/11307074.html
總結(jié)
以上是生活随笔為你收集整理的理解Promise (4)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 在派生类中引发基类事件
- 下一篇: TS中补充的六个类型