我的promise能實現(xiàn)什么?

          1:解決回調(diào)地獄,實現(xiàn)異步

          2:可以鏈?zhǔn)秸{(diào)用,可以嵌套調(diào)用

          3:有等待態(tài)到成功態(tài)的方法,有等待態(tài)到失敗態(tài)的方法


          4:可以衍生出周邊的方法,如Promise.resolve(),Promise.reject(),Promise.prototype.then(),Promise.prototype.catch(),Promise.all()
          // 所有的完成

          5. 可以根據(jù)自己的需求調(diào)節(jié)自己的promise
          let PromiseA = require('./PromiseA'); const promiseA = new PromiseA((resolve,
          reject) => { resolve(new PromiseA((resolve,reject)=>{ setTimeout(()=>{ resolve(
          100) },1000) })) }) promiseA.then(data=>{ console.log(data) })
          下面開始實現(xiàn)promise,首先創(chuàng)造三個常量,等待,成功,失敗
          const PENDING = 'PENDING'; // 等待狀態(tài) const RESOLVED = 'RESOLVED'; // 成功狀態(tài) const
          REJECTED = 'REJECTED';// 失敗狀態(tài)

          然后創(chuàng)造一個promiseA類,里面有constructor,then方法,catch方法。這里的catch其實就是失敗的then,即then(null,(err)=>{...})

          class PromiseA { constructor(){...} then(){...}  ????catch(err){
          ????????return?this.then(null,err) ????} }

          我們重點關(guān)注constructor和then,先來看constructor。這里promiseA默認的狀態(tài)是等待態(tài),成功的值value默認為undefined,失敗的值reason默認為undefined。這里的onResolvedCallbacks和onRejectedCallbacks是一個發(fā)布訂閱的數(shù)組,我們先不管。然后有resolve方法,reject方法

          還有Promise自帶一個executor執(zhí)行器,就是傳進來的參數(shù)。會立即執(zhí)行 。 但有可能出錯。所以用try,catch包住。
          executor里有倆個參數(shù),就是resolve和reject。就是promise傳進來參數(shù)的倆個resolve,reject方法.
          constructor(executor) { this.status = PENDING; // 默認等待狀態(tài) this.value =
          undefined;this.reason = undefined; this.onResolvedCallbacks = []; this
          .onRejectedCallbacks = []; let resolve = (value) => { if(value instanceof
          PromiseA){ value.then(resolve,reject)return } if (this.status === PENDING) {
          this.value = value; this.status = RESOLVED; this.onResolvedCallbacks.forEach(fn
          => fn()); } } let reject = (reason) => { if (this.status === PENDING) { this
          .reason = reason; this.status = REJECTED; this.onRejectedCallbacks.forEach(fn =>
          fn()); } }try { executor(resolve, reject); } catch (e) { reject(e) } }

          然后我們在看看then,then里面?zhèn)鬟M來倆個參數(shù),其實就是倆個方法。一個成功的回調(diào),一個失敗的回調(diào)。我們重點看一下,三個狀態(tài)的執(zhí)行,即status的走向。如果是resolve,即執(zhí)行成功的回調(diào)onFulfilled。如果是reject,即執(zhí)行失敗的回調(diào)onRejected。如果是等待,即執(zhí)行一個發(fā)布訂閱的模式,發(fā)布訂閱,其實就是,我先將成功的回調(diào)或者的失敗的回調(diào)各自放入對應(yīng)的數(shù)組,即是上面我們跳過的倆個數(shù)組onResolvedCallbacks和onRejectedCallbacks
          。然后,當(dāng)狀態(tài)改變?yōu)閞esolve或者reject的時候,即遍歷執(zhí)行對應(yīng)的回調(diào)函數(shù)。至此異步就實現(xiàn)了,回調(diào)地獄解決。這個異步解決就是靠發(fā)布訂閱模式來解決的。
          then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled ===
          'function' ? onFulfilled:v=>v onRejected = typeof onRejected === 'function' ?
          onRejected:e=>{throw e} let promise2 = new PromiseA((resolve, reject) => { if (
          this.status === RESOLVED) { setTimeout(() => { try { let x = onFulfilled(this
          .value); resolvePromise(promise2, x, resolve, reject); }catch (e) { reject(e) }
          }); }if (this.status === REJECTED) { setTimeout(() => { try { let x =
          onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch
          (e) { reject(e) } }); }if (this.status === PENDING) { this
          .onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulfilled(
          this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) {
          reject(err); } }); })this.onRejectedCallbacks.push(() => { setTimeout(() => {
          try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve,
          reject); }catch (e) { reject(err); } }); }) } }) return promise2; }
          接下來我們繼續(xù)實現(xiàn)鏈?zhǔn)秸{(diào)用,既是一個promiseA.then的結(jié)果返回的e是promise2的then的data。
          一個成功的結(jié)果返回給下一個then作為參數(shù)。
          let promise2 = promiseA.then(e=>{ return e } ) promise2.then(data=>{
          console.log(data,'123') })
          那么繼續(xù)實現(xiàn),還是上面的函數(shù)。這里我們重點觀察這個promise2和setTimeout和resolvePromise.
          我們先說promise2,這里的promise2,其實是一個新的promise.也就是說promise的鏈?zhǔn)秸{(diào)用靠的就是返回一個新的promise.這里把之前的三種狀態(tài)包起來,目的就是可以讓里面得到的結(jié)果,獲取給promise2的resolve和reject。有人可能會說,那么promise2的resolve或者reject要還是promise怎么辦?這里我們就要用到resolvePromise方法來判斷了。所以我們將成功的回調(diào)函數(shù)resolve換成resolvePromise方法來執(zhí)行。這里我們要明白,resolve是執(zhí)行成功的回調(diào)函數(shù)。不管狀態(tài)是成功還是失敗,如果執(zhí)行成功都是走向resolve。所以resolve和reject的狀態(tài)如果執(zhí)行成功都是走向resolve。
          let promise2 = new PromiseA((resolve, reject) => { if (this.status ===
          RESOLVED) { setTimeout(()=> { try { let x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject); }catch (e) { reject(e) } }); } if
          (this.status === REJECTED) { setTimeout(() => { try { let x = onRejected(this
          .reason); resolvePromise(promise2, x, resolve, reject); }catch (e) { reject(e)
          } }); }if (this.status === PENDING) { this.onResolvedCallbacks.push(() => {
          setTimeout(()=> { try { let x = onFulfilled(this.value);
          resolvePromise(promise2, x, resolve, reject); }catch (e) { reject(err); } }); })
          this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x =
          onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch
          (e) { reject(err); } }); }) } })return promise2;

          然后我們在看resolvePromise方法,走到這里,說明是執(zhí)行成功的回調(diào)函數(shù)了。傳進去的參數(shù)有promise2,x,promise2的resolve,promise2的reject。首先promise2是一個new
          promise。 這樣傳進去參數(shù)是會報錯的。因為執(zhí)行到這一步,promise2還沒有生成。所以是會報錯的。


          所以我們加一個setTimeout包住它,這樣就可以等promise2生成完在執(zhí)行。這里的setTimeout涉及到了事件循環(huán),也就是宏任務(wù)和微任務(wù)的部分。js執(zhí)行機制是先執(zhí)行主線程,然后執(zhí)行微任務(wù)隊列,然后進行渲染,然后在執(zhí)行宏任務(wù)隊列。宏任務(wù)執(zhí)行完,如果宏任務(wù)里還包著js任務(wù),就繼續(xù)循環(huán)反復(fù)。直到所有任務(wù)執(zhí)行完成。這里的setTimeout是宏任務(wù),
          resolvePromise(promise2, x, resolve, reject);
          剛剛說到setTimeout,這里貼上一段代碼。這里的newPromise是在setTimeout前執(zhí)行的。
          console.log(1); setTimeout(() => { console.log("我是定時器,延遲0S執(zhí)行的"); }, 0); new
          Promise((resolve, reject) => { console.log("new Promise是同步任務(wù)里面的宏任務(wù)"); resolve(
          "我是then里面的參數(shù),promise里面的then方法是宏任務(wù)里面的微任務(wù)"); }).then(data => { console.log(data);
          }); console.log(2);


          ?

          ?


          好的參數(shù)都傳進去了,接下來我們看resolvePromise的具體方法。就是一個判斷回調(diào)函數(shù)x是不是promise,如果是就在循環(huán)拆開。直到不是為止。如果是普通值的話就可以直接返回了。至此,所以的promise庫就實現(xiàn)完了。至于后面的all和其他周邊方法就是語法糖了。主要核心部分掌握了,后面的周邊方法就不算什么了。
          function resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) {
          return reject(new TypeError('返回的promise和當(dāng)前promise不能是同一個對象哦,會嵌入死循環(huán)')) } if ((
          typeof x === 'object' && x !== null) || typeof x === 'function') { try { let
          then= x.then; if (typeof then === 'function') { then.call(x,y=> {
          resolvePromise(promise2, y, resolve, reject) },r=> { reject(r) } ) } else {
          resolve(x) } }catch (err) { reject(err) } } else { resolve(x); } }
          ?至于resolve方法里判斷,我們來看看。其實也是一個遞歸。判斷PromiseA里的resolve里面是不是promise,一直拆開。跟上面的方法類似。
          let resolve = (value) => { if(value instanceof PromiseA){
          value.then(resolve,reject)return } if (this.status === PENDING) { this.value =
          value;this.status = RESOLVED; this.onResolvedCallbacks.forEach(fn => fn()); } }
          而至于這倆行代碼,就是解決一個不斷向jquery那樣then的情況。如果是函數(shù)的話,將自己的參數(shù)作為結(jié)果返回。傳遞給下一個then。
          onFulfilled = typeof onFulfilled === 'function' ? onFulfilled:v=>v onRejected
          =typeof onRejected === 'function' ? onRejected:e=>{throw e}
          promiseA.then().then().then().then().then()
          ?

          ?

          最后,如果有什么覺得奇怪的地方,歡迎互相討論,學(xué)習(xí)。謝謝!

          友情鏈接
          ioDraw流程圖
          API參考文檔
          OK工具箱
          云服務(wù)器優(yōu)惠
          阿里云優(yōu)惠券
          騰訊云優(yōu)惠券
          京東云優(yōu)惠券
          站點信息
          問題反饋
          郵箱:[email protected]
          QQ群:637538335
          關(guān)注微信

                免费成人A片视频 | 高清无码视频观看 | 91狠狠综合 | 一区无码精品 | 好大好深好爽视频 |