手把手教你實現Promise(二)(基於Promise A+規範)

lily醬發表於2019-02-23
前面,我們已經實現了一個自己的Promise。但是,還有一些功能沒有實現。現在就一起實現一下吧(*^ワ^*)。 

catch 

  • catch是用於指定發生錯誤時的回撥函式。
  • catch()使回撥報錯時不會卡死js而是會繼續往下執行。
  • Promise 物件的錯誤具有穿透性,會一直向後傳遞,直到被捕獲為止。也就是說,錯誤總是會被下一個catch語句捕獲。 

用法:

let promise = new Promise((resolve, reject) => {
    reject(`?`)
})
promise.then((data) => {
    console.log(data)
}).catch(e => {
    console.log(`my` + e)
})複製程式碼

實現思路:

我們知道then方法中,如果第一個不寫對應的方法,會穿透到下一個then方法;而第二個then裡,只要有reject對應的方法就可以實現。
所以這裡的catch方法等於第二個then,沒有寫resolve對應的方法,只寫了 reject對應的方法。 

 那麼,我們可以在原型上新增這樣的方法:

catch (fn) {
    return this.then(null, fn)
  } 複製程式碼

all 

Promise.all方法用於將多個Promise例項,包裝成一個新的Promise例項。 

用法:

Promise.all([p1, p2, p3]).then(function(values) {
  console.log(values);
}); 複製程式碼
  • all()接受陣列作為引數。p1,p2,p3都是Promise的例項物件,Promise要變成Resolved狀態需要p1,p2,p3狀態都是Resolved,如果p1,p2,p3中有一個狀態是Rejected,p的狀態就變成Rejected。 
  • 成功和失敗的返回值是不同的,成功的時候返回的是一個結果陣列,而失敗的時候則返回最先被reject失敗狀態的值 

實現思路:

all方法裡存一個陣列,然後把p1, p2, p3執行後的結果放到對應的陣列裡。如果有一個錯誤了,直接走調失敗回撥。

Promise.all = (promises) => {
  return new Promise((resolve, reject) => {
    let result = []; //最終返回值的結果
    let index = 0;
    let processData = (key, y) => {
      index++
      result[key] = y;
      if (promises.length === index) {
        resolve(result);
      }
    }
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(y => {
        processData(i, y);
      }, reject);
    }
  })
}複製程式碼

race

Promse.race就是賽跑的意思,意思就是說,Promise.race([p1, p2, p3])裡面哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態  

用法:

Promise.race([p1, p2, p3]).then(function(value) {
  console.log(value);
}); 複製程式碼

實現思路: 

它跟all方法很像,但是它不需要等待其他例項執行結果,p1, p2, p3誰先執行完就執行誰的then方法。

Promise.race =(promises) => {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(resolve, reject);
    }
  })
} 複製程式碼

resolve 

有時需要將現有物件轉為Promise物件,Promise.resolve方法就起到這個作用。 

用法:

Promise.resolve(`?`) 複製程式碼

實現如下:

Promise.resolve = function (data) {
  return new Promise((resolve,reject)=>{
    resolve(data);
  })
} 複製程式碼

reject

Promise.reject(reason)方法也會返回一個新的 Promise 例項,該例項的狀態為rejected。 

用法:

Promise.reject(`❌`) 複製程式碼

實現如下: 

Promise.reject = function (data) {
  return new Promise((resolve, reject) => {
    reject(data);
  })
} 複製程式碼

目前,我們就實現了一個比較完整的Promise(⌒_⌒)。

相關文章