亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript手寫Promise核心原理

 更新時間:2022年06月24日 11:39:05   作者:??遠方的小草????  
這篇文章主要介紹了JavaScript手寫Promise核心原理,promise?可以說是出場率很高的api了,這篇文章手寫一版promise,可以加強對promise的認識

準(zhǔn)備

  • 首先,promise 有三種狀態(tài):pending fulfilled rejected;
  • promise在實例化操作中, 有兩個改變狀態(tài)的方法,分別為resolve,reject;
  • promise有很多方法,詳情請見 mdn, 本篇文章先實現(xiàn) promise的核心apithencatch;

我們使用 es6 提供的 class 來實現(xiàn)

class MyPromise {
 // 準(zhǔn)備三個狀態(tài)
 static PENDING = 'pending';
 static FULFILLED = 'fulfilled';
 static REJECTED = 'rejected';

 constructor(executor) {
   this.status = MyPromise.PENDING; // 表示promise的狀態(tài)
   this.value = null;  // 表示promise的值
   try {
     executor(this.resolve.bind(this), this.reject.bind(this))
   } catch (error) {
     this.reject(error)
   }
 }
 resolve() {
 }
 reject() {
 }
}

在這里 executor 就是傳遞過來的函數(shù),可以接收 resolvereject,這里將內(nèi)部的兩個方法給傳入,如果在調(diào)用的過程中報錯了會調(diào)用reject方法

完善 resolve/reject

他們做的工作分為以下幾部

  • 將狀態(tài)改為pendingfulfilled 或 rejected
  • 可以接受一個值為當(dāng)前的promisevalue
  resolve(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = value
    }
  }
  reject(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = value
    }
  }

then

then 函數(shù)可以接受兩個參數(shù),分別為成功的回調(diào)函數(shù)和失敗的回調(diào)函數(shù),并且回調(diào)函數(shù)的默認為一個函數(shù)

  • 狀態(tài)為 fulfilled 執(zhí)行第一個回調(diào),rejected 執(zhí)行第二個回調(diào)
  • 回調(diào)函數(shù)中給傳入當(dāng)前的 value
  • then的執(zhí)行為異步的
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }

    if (this.status === MyPromise.FULFILLED) {
      setTimeout(() => {
        onFulfilled(this.value)
      })
    }

    if (this.status === MyPromise.REJECTED) {
      setTimeout(() => {
        onRejected(this.value)
      })
    }
  }

驗證一下:

console.log(1)
new MyPromise((resolve, reject) => {
  console.log(2)
  resolve('成功')
}).then(res => console.log(res))

console.log(3)

// 打印 1 2 3 成功

當(dāng)promise里面有異步代碼的時候,這個時候運行到.then方法 狀態(tài)為pending,下來增加一下異步任務(wù)的處理

異步處理

當(dāng)狀態(tài)為pending的時候,表示執(zhí)行的是異步任務(wù),這個時候我們可以增加一個callback,把異步執(zhí)行的內(nèi)容添加到這個callback中,當(dāng)執(zhí)行完異步代碼的時候,會執(zhí)行異步函數(shù)的callback的任務(wù)

constructor(executor) {
  // ...
  this.callbacks = []; // 用來存儲回調(diào)函數(shù)的容器
  // ...
}
resolve(value) {
  // ...
  this.callbacks.forEach(({ onFulfilled }) => onFulfilled(value)) 
  // 當(dāng)執(zhí)行到這里的時候 如果有onFulfilled 就說明已經(jīng)執(zhí)行完then方法給容器添加內(nèi)容了。把resolve的值傳遞給onFulfilled
} 
reject(value) {
  // ...
  this.callbacks.forEach(({ onRejected }) => onRejected(value))
  // 當(dāng)執(zhí)行到這里的時候 如果有onRejected 就說明已經(jīng)執(zhí)行完then方法給容器添加內(nèi)容了。把reject的值傳遞給onFulfilled
}
then(onFulfilled, onRejected) {
  // ...
  if (this.status === MyPromise.PENDING) {
    this.callbacks.push({
      onFulfilled: value => {
        setTimeout(() => {
          onFulfilled(value)
        })
      },
      onRejected: value => {
        setTimeout(() => {
          onRejected(value)
        })
      }
    })
  }
 }

驗證一下:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(res => console.log(res)) 

// 打印  成功

then 函數(shù)可以鏈?zhǔn)秸{(diào)用,接下來我們完善一下

鏈?zhǔn)秸{(diào)用

鏈?zhǔn)秸{(diào)用的核心就是返回一個新的 promise,當(dāng)成功調(diào)用的時候調(diào)用新的promiseresolve,失敗reject,并且鏈?zhǔn)秸{(diào)用會把前一個的返回值當(dāng)作下一個的 resolve 的狀態(tài)

then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          resolve(result)
        })
      }

      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onRejected(this.value)
          resolve(result) 
        })
      }
      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            setTimeout(() => {
              const result = onFulfilled(value)
              resolve(result)
            })
          },
          onRejected: value => {
            setTimeout(() => {
              const result = onRejected(value)
              resolve(result)
            })
          }
        })
      }
    })
  }

驗證一下:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject('失敗')
  })
}).then(res => res, err => err).then(res => console.log(res))

// 打印  失敗

如果.then的回調(diào)函數(shù)返回的是promise的情況也要做個處理

邊界處理

實現(xiàn)前:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(
  res => new MyPromise((resolve, reject) => {
    resolve(res)
  }),
  err => err
).then(res => console.log(res))

// 打印  { "status": "fulfilled", "value": "成功", "callbacks": [] }

當(dāng)判斷返回值為 MyPromise 的時候,需要手動調(diào)用 .then 的方法取他的值,并且吧當(dāng)前的 promise 的改變狀態(tài)的函數(shù)透出給 then 方法

  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          if (result instanceof MyPromise) { 
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }

      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onRejected(this.value)
          if (result instanceof MyPromise) {
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }

      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            setTimeout(() => {
              const result = onFulfilled(value)
               if (result instanceof MyPromise) {
                 result.then(resolve, reject)
               } else {
                resolve(result)
               }
            })
          },
          onRejected: value => {
            setTimeout(() => {
              const result = onRejected(value)
              if (result instanceof MyPromise) {
                result.then(resolve, reject)
              } else {
                resolve(result)
              }
            })
          }
        })
      }
    })
  }

驗證:

new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  })
}).then(
  res => new MyPromise((resolve, reject) => {
    resolve(res)
  }),
  err => err
).then(res => console.log(res))

// 打印  成功

到這里 .then 方法就實現(xiàn)差不多了,接下來實現(xiàn) catch 方法

catch

catch 方法可以處理拒絕的狀態(tài)和錯誤的狀態(tài):

  catch(onFulfilled) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          const result = onFulfilled(this.value)
          if (result instanceof MyPromise) {
            result.then(resolve, reject)
          } else {
            resolve(result)
          }
        })
      }
    })
  }

驗證:

new MyPromise((resolve, reject) => {
  reject('失敗')
}).catch(res=> console.log(res))

// 打印  失敗

道理其實和 then 是相同的,到這里主功能基本上就差不多了,但是有很多重復(fù)的地方,優(yōu)化一下

優(yōu)化后完整代碼

class MyPromise {
  // 準(zhǔn)備三個狀態(tài)
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';

  constructor(executor) {
    this.status = MyPromise.PENDING; // 表示promise的狀態(tài)
    this.value = null;  // 表示promise的值
    this.callbacks = [];
    try {
      executor(this.resolve.bind(this), this.reject.bind(this))
    } catch (error) {
      console.log(error)
      this.reject(error)
    }
  }
  resolve(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.FULFILLED;
      this.value = value
    }
    this.callbacks.forEach(({ onFulfilled }) => onFulfilled(value))
  }
  reject(value) {
    if (this.status === MyPromise.PENDING) {
      this.status = MyPromise.REJECTED;
      this.value = value
    }
    this.callbacks.forEach(({ onRejected }) => onRejected(value))
  }
  parse({ callback, resolve, reject, value = this.value }) {
    setTimeout(() => {
      const result = callback(value)
      if (result instanceof MyPromise) {
        result.then(resolve, reject)
      } else {
        resolve(result)
      }
    })
  }
  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    if (typeof onFulfilled !== 'function') {
      onRejected = value => value
    }
    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.FULFILLED) {
        this.parse({ callback: onFulfilled, resolve, reject })
      }

      if (this.status === MyPromise.REJECTED) {
        this.parse({ callback: onRejected, resolve, reject })
      }

      if (this.status === MyPromise.PENDING) {
        this.callbacks.push({
          onFulfilled: value => {
            this.parse({ callback: onFulfilled, resolve, reject, value })
          },
          onRejected: value => {
            this.parse({ callback: onRejected, resolve, reject, value })
          }
        })
      }
    })
  }
  catch(onFulfilled) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = value => value
    }

    return new MyPromise((resolve, reject) => {
      if (this.status === MyPromise.REJECTED) {
        this.parse({ callback: onFulfilled, resolve, reject })
      }
    })
  }
}

到此這篇關(guān)于JavaScript手寫Promise核心原理的文章就介紹到這了,更多相關(guān)JavaScript Promise內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論