日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现一个符合 Promise/A+ 规范的 MyPromise

發(fā)布時間:2025/3/17 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现一个符合 Promise/A+ 规范的 MyPromise 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Promise

實(shí)現(xiàn)一個符合 Promise/A+ 規(guī)范的 MyPromise,并實(shí)現(xiàn) resolve、reject、all、race、defer、deferred等靜態(tài)方法。

MyPromise

  • 作用:創(chuàng)建 MyPromise實(shí)例。Promise
  • MyPromise接收一個回掉函數(shù) executor
  • MyPromise狀態(tài)
    • pending
      • 可以轉(zhuǎn)換成 fulfilled 或 rejected
    • fulfilled
      • 不可改變成其他狀態(tài)
    • rejected
      • 不可改變成其他狀態(tài)
  • onFulfilledCallbacks 和 onRejectedCallbacks
    • 兩個數(shù)組,數(shù)組每一項(xiàng)是一個函數(shù)。分別接收then里面的第一個參數(shù)和第二個參數(shù)。
    • 狀態(tài)是 pending 的回掉函數(shù)。
  • resolve
    • promise的狀態(tài)是fulfilled異常是的處理函數(shù)
    • 接收 value 參數(shù)
      • 如果是promise,執(zhí)行then。
      • 如果不是promise,把value做為參數(shù)傳給onFulfilledCallbacks里的每個函數(shù)。
  • reject
    • promise的狀態(tài)是rejected異常是的處理函數(shù)
    • 接收 reason 參數(shù),把reason做為參數(shù)傳給onRejectedCallbacks里的每個函數(shù)。
  • 執(zhí)行 executor,如果有異常,拋給reject
  • 因?yàn)镻romise是在同步代碼執(zhí)行完成后再執(zhí)行,所以要把Mypromise的執(zhí)行方法resolve和reject放在異步隊(duì)列里
  • function MyPromise(executor) {if (typeof executor !== 'function') {throw new TypeError('Promise resolver ' + executor + ' is not a function');}let self = this;this.status = 'pending';this.value = undefined;this.reason = undefined;this.onFulfilledCallbacks = [];this.onRejectedCallbacks = [];function resolve(value) {if (value instanceof MyPromise) {return value.then(resolve, reject);}if (self.status === 'pending') {self.value = value;self.status = 'fulfilled';self.onFulfilledCallbacks.forEach(item => item(value));}}function reject(reason) {if (self.status === 'pending') {self.reason = reason;self.status = 'rejected'; self.onRejectedCallbacks.forEach(item => item(reason));}}try {executor(resolve, reject);} catch (e) {reject(e);} }復(fù)制代碼

    MyPromise.prototype.then

  • 作用:接收兩個函數(shù)參數(shù),第一個函數(shù)的參數(shù)是 resolve傳入的參數(shù),第二個參數(shù)是 reject傳入的參數(shù)。Promise#then
  • onFulfilled
    • MyPromise 成功時執(zhí)行的方法
    • resolve 的參數(shù)會作為value傳給 onFulfilled
  • onRejected
    • MyPromise 失敗時執(zhí)行的方法
    • reject 的參數(shù)會作為value傳給 onRejected
  • 返回一個 MyPromise 實(shí)例 newPromise,方便鏈?zhǔn)秸{(diào)用
  • 對三種狀態(tài)分別處理
    • 每個狀態(tài)中創(chuàng)建 newPromise
    • fulfilled
      • 直接執(zhí)行 onFulfilled,返回值x
      • 把newPromise、x以及newPromise里的resolve、reject做為參數(shù)傳給 resolutionPromise
      • 把 MyPromise 的參數(shù)放在異步隊(duì)列里
    • rejected
      • 直接執(zhí)行 onRejected,返回值x
      • 把newPromise、x以及newPromise里的resolve、reject做為參數(shù)傳給 resolutionPromise
      • 把 MyPromise 的參數(shù)放在異步隊(duì)列里
    • pending
      • 狀態(tài)待定,把fulfilled和rejected里的異步函數(shù)分別加到 onFulfilledCallbacks 和 onRejectedCallbacks的最后一位
  • resolutionPromise 后面細(xì)說
  • 用catch捕獲異常,執(zhí)行 reject
  • MyPromise.prototype.then = function (onFulfilled, onRejected) {let self = this;typeof onFulfilled !== 'function' && (onFulfilled = function (value) {return value;});typeof onRejected !== 'function' && (onRejected = function (reason) {throw reason;});let newPromise;/*** 分別處理實(shí)例的三種狀態(tài)*/if (self.status === 'fulfilled') {newPromise = new MyPromise(function (resolve, reject) {setTimeout(function () {try {let x = onFulfilled(self.value);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});}if (self.status === 'rejected') {newPromise = new MyPromise(function (resolve, reject) {setTimeout(function () {try {let x = onRejected(self.reason);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});}if (self.status === 'pending') {newPromise = new MyPromise(function (resolve, reject) {self.onFulfilledCallbacks.push(function (value) {setTimeout(function () {try {let x = onFulfilled(value);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});self.onRejectedCallbacks.push(function (reason) {setTimeout(function () {try {let x = onRejected(reason);resolutionPromise(newPromise, x, resolve, reject);} catch (e) {reject(e);}});});});}return newPromise; };復(fù)制代碼

    MyPromise.prototype.catch

  • 作用:捕獲異常
  • 返回 MyPromise
  • MyPromise.prototype.catch = function (onRejected) {return this.then(undefined, onRejected); }; 復(fù)制代碼

    The Promise Resolution Procedure

  • Promise解析過程,是以一個 promise、一個值 x及resolve, reject做為參數(shù)的抽象過程
  • promise 等于 x,reject 拋出異常 new TypeError('循環(huán)引用')
  • x如果不是對象(不包括 null)或者函數(shù),執(zhí)行 resolve(x)
  • 獲取 x.then 賦值給 then
    • then 如果是 function
      • 把 x做為 this 調(diào)用then,第一個參數(shù)是 resolvePromise,第二個參數(shù)是 rejectPromise
      • resolvePromise和 rejectPromise只有第一次調(diào)用有效
      • resolvePromise參數(shù)為 y,執(zhí)行 resolutionPromise(promise, y, resolve, reject)
      • rejectPromise參數(shù)為 r,執(zhí)行 reject(r)
    • then 如果不是 function
      • 執(zhí)行 resolve(x)
  • 用捕獲上一步的異常
    • 執(zhí)行 reject(e)
    • 如果執(zhí)行過 resolvePromise或 rejectPromise,忽略
  • function resolutionPromise(promise, x, resolve, reject) {if (promise === x) {reject(new TypeError('循環(huán)引用'));}let then, called;if (x !== null && (typeof x === 'object' || typeof x === 'function')) {try {then = x.then;if (typeof then === 'function') {then.call(x, function (y) {if (called)return;called = true;resolutionPromise(promise, y, resolve, reject);}, function (r) {if (called)return;called = true;reject(r);})} else {resolve(x);}} catch (e) {if (called)return;reject(e);}} else {resolve(x);} } 復(fù)制代碼

    MyPromise 靜態(tài)方法

    MyPromise.all

    • 作用:Promise.all
    MyPromise.all = function (promises) {let called = false;return new MyPromise(function (resolve, reject) {let newArr = [], count = 0;for (let i = 0; i < promises.length; i++) {let item = promises[i];if (!(item instanceof MyPromise)) {item = MyPromise.resolve(item);}item.then(function (data) {if (!called) {newArr[i] = data;if (i == count) {resolve(newArr);count++;}}}, function (e) {if (!called) {reject(e);called = true;}});}}); }; 復(fù)制代碼

    MyPromise.race

    • 作用:Promise.race
    MyPromise.race = function (promises) {return new MyPromise(function (resolve, reject) {let called = false;for (let i = 0; i < promises.length; i++) {let item = promises[i];if (!(item instanceof MyPromise)) {item = MyPromise.resolve(item);}item.then(function (data) {if (!called) {resolve(data);called = true;}}, function (e) {if (!called) {reject(e);called = true;}});}}) }; 復(fù)制代碼

    MyPromise.resolve

    • 作用:Promise.resolve
    MyPromise.resolve = function (value) {if (value instanceof MyPromise) {return value;}return new MyPromise(function (resolve, reject) {if (typeof value !== null && typeof value === 'object' && typeof value.then === 'function') {value.then();} else {resolve(value);}}) }; 復(fù)制代碼

    MyPromise.reject

    • 作用:Promise.reject
    MyPromise.reject = function (e) {return new MyPromise(function (resolve, reject) {reject(e);}) }; 復(fù)制代碼

    test

    • npm i -g promises-aplus-tests
    • promises-aplus-tests Promise.js

    源碼

    • Promise.js
    參考資料
    • Promise/A+規(guī)范
    • Promise/A+規(guī)范(英文)
    • JavaScript Promise迷你書(中文版)

    總結(jié)

    以上是生活随笔為你收集整理的实现一个符合 Promise/A+ 规范的 MyPromise的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。