91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript怎么實現簡易的Promise對象

發布時間:2022-12-01 10:07:28 來源:億速云 閱讀:128 作者:iii 欄目:開發技術

這篇“JavaScript怎么實現簡易的Promise對象”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“JavaScript怎么實現簡易的Promise對象”文章吧。

前言

實現一個簡易的Promise對象,我們首先要了解幾個相關的知識點:

Promise對象的狀態: pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。這也是Promise這個名字的由來,它的英語意思就是“承諾”,表示其他手段無法改變。

Promise的參數: Promise構造函數接收一個函數作為參數,函數內部有兩個參數,分別是resolve和reject,這兩個參數是兩個函數,由JS引擎提供,不需要我們部署。reslove函數的作用是將Promise對象的狀態由 'pending' 狀態變為 'resolved'狀態即('fulfilled'狀態),方便與參數名對應,reject函數的作用是將Promise對象的狀態由 'pending' 狀態變為 'rejected'狀態。

但是我們應該注意的是,Promise對象的狀態一經改變,就不再發生改變(即pending --> resolved || pending --> rejected 其中任意一種發生改變之后,Promise對象的狀態將不再發生改變)

Promise的基礎結構與用法

 let p1 = new Promise((resolve, reject) => {
   resolve('成功');
   reject('失敗');
   throw('報錯');  //相當于reject()
 })

 console.log(p1);

讓我們看看三種狀態的打印的結果分別是什么吧

JavaScript怎么實現簡易的Promise對象

JavaScript怎么實現簡易的Promise對象

JavaScript怎么實現簡易的Promise對象

使用class類實現promise對象

class myPromise {
  constructor(executor) {
    this.status = 'pending'; // 變更promise的狀態
    this.value = null;
    
    executor(this.resolve, this.reject); // new 一個myPromise 得到的實例對象里面有兩個函數
  }

  resolve(value) {
    if (this.status !== 'pending') return;
    this.status = 'fulfilled'; // 變更promise的狀態
    this.value = value;
  }

  reject(reason) {
    if (this.status !== 'pending') return
    this.status = 'rejected';
    this.value = reason;
  }
}

貌似這么寫代碼邏輯也說得通,那么讓我們看一下實現的效果:

JavaScript怎么實現簡易的Promise對象

看到這里,不難想到我們的resolve和reject的兩個方法的this指向出現了問題,我們仔細看看不難發現,這兩個方法被我們作為實參放到了構造器函數,此時this的指向是指向了構造器函數,而不是我們寫的myPromise這個構造函數身上,那只需要bind顯示綁定一下this 的指向就可以解決了。

executor(this.resolve.bind(this), this.reject.bind(this))

JavaScript怎么實現簡易的Promise對象

并且myPromise的狀態一經變更也不再改變,是不是有一點原裝Promise的味道了。但是在Promise里面還有一個錯誤捕捉機制,只要promise里面執行的邏輯報錯了,就需要走reject邏輯,將錯誤拋出來,那我們只需要使用try catch來實現就可以。

try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error)
    }

這樣我們就實現了極簡版的Promise對象,但是通常情況下我們都是使用Promise對象來處理異步的問題,說到異步,那不得不提起Promise.prototype.then()這個方法了,then方法返回的是一個新的Promise實例(注意,不是原來那個Promise實例)。因此可以采用鏈式寫法,即then方法后面再調用另一個then方法。

then方法的第一個參數是`resolved狀態的回調函數`,第二個參數是`rejected狀態的回調函數`,它們都是可選的。

當promise的狀態為'fulfilled'會執行第一個回調函數,當狀態為'rejected'時執行第二個回調函數。

必須等到Promise的狀態變更過一次之后,狀態為'fulfilled'或者'rejected',才去執行then里面的邏輯。

.then支持鏈式調用,下一次.then受上一次.then執行結果的影響。

知道以上這幾點,我們就可以嘗試如何實現.then方法了

class myPromise {
  constructor(executor) {
    this.status = 'pending'; 
    this.value = null;
    this.onFulfilledCallbacks = []; // 用來保存成功的回調(處理異步)
    this.onRejectedCallbacks = []; // 用來保存失敗的回調(處理異步)
    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error)
    }
  }

  resolve(value) {
    if (this.status !== 'pending') return;
    this.status = 'fulfilled';
    this.value = value;
    // 調用then里面的回調
    while (this.onFulfilledCallbacks.length) { // 當異步成功回調數組中存在回調函數,那就執行
      this.onFulfilledCallbacks.shift()(this.value)
    }
  }

  reject(reason) {
    if (this.status !== 'pending') return
    this.status = 'rejected';
    this.value = reason;
    while (this.onRejectedCallbacks.length) { // 當異步失敗回調數組中存在回調函數,那就執行
      this.onRejectedCallbacks.shift()(this.value)
    }
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val  // 判斷.then的第一個參數是不是一個函數,如果不是就直接作為結果返回
    onRejected = typeof onRejected === 'function' ? onRejected : val => { throw val } // 判斷.then的第二個參數是不是一個函數,如果不是就直接作為錯誤返回

    var thenPromise = new myPromise((resolve, reject) => {  // 因為.then返回的是一個心的Promise對象

      const resolvePromise = callback => {  // 用于判斷回調函數的類型
        setTimeout(() => {   // 讓整個回調函數比同步代碼晚一點執行,官方不是使用setTimeout實現
          try {
            const x = callback(this.value);
            if (x === thenPromise) {  // 你正在返回自身
              throw new Error('不允許返回自身!');
            }
            if (x instanceof myPromise) { // 返回的是一個Promise對象
              x.then(resolve, reject);
            } else { // 直接返回一個值,作為resolve的值,傳遞給下一個.then
              resolve(x);
            }
          } catch (error) {
            reject(error);
            throw new Error(error)
          }
        })
      }

      if (this.status === 'fulfilled') {
        resolvePromise(onFulfilled)
      } else if (this.status === 'rejected') {
        resolvePromise(onRejected)
      } else if (this.status === 'pending') {
        this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled));
        this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected));
      }
    })
    return thenPromise
  }
}

JavaScript怎么實現簡易的Promise對象

以上就是關于“JavaScript怎么實現簡易的Promise對象”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彭水| 五家渠市| 道真| 丰顺县| 长兴县| 东阿县| 宁远县| 凤台县| 信丰县| 霍州市| 吴旗县| 宁国市| 鄯善县| 伊春市| 巴南区| 阜城县| 绩溪县| 喜德县| 甘肃省| 保靖县| 盐津县| 永靖县| 永年县| 桦南县| 清河县| 漾濞| 平塘县| 石首市| 阳朔县| 隆子县| 静宁县| 榕江县| 巫山县| 井冈山市| 阳泉市| 宜君县| 胶州市| 中西区| 三门峡市| 喀喇沁旗| 永和县|