实现 Promise 的 catch、finally、resolve、reject、all、race、allSettle 等方法

·  阅读 121
实现 Promise 的 catch、finally、resolve、reject、all、race、allSettle 等方法

前言

上篇文章中实现了符合 Promise/A+ 规范的 Promise。本篇我们来实现 Promise 的常用原型方法和静态方法。

Promise.prototype.catch

promise.catch(onRejcted)
复制代码

catch()  方法返回一个 Promise 对象,并且处理失败的情况。是Promise.prototype.then(undefined, onRejected)的简写。

参数

  • onRejected

    Promise 失败时调用的函数。该函数拥有一个参数:reason,失败的原因。

返回值

一个 Promise 对象。

如果 onRejected抛出一个错误或返回一个失败的 Promise 对象,则返回一个失败Promise。否则返回一个成功Promise 对象。

实现

Promise.prototype.catch = function (onRejected) {
  return this.then(null, onRejected)
}

复制代码

Promise.prototype.finally

promise.finally(onFinally);
复制代码

finally() 方法返回一个 Promise 对象。在这个 Promise 结束时,无论结果成功还是失败,都会执行 onFinally

避免同样的语句需要在 onFulfilledonRejected 中各写一次的情况。

参数

  • onFinally

    Promise 结束后调用的函数。

返回值

一个设置了 finally 回调函数的 Promise 对象。

实现

//  错误实现
// Promise.prototype.finally = (onFinally) => {
//   return this.then(onFinally, onFinally)
// }

// 正确实现
Promise.prototype.finally = function (onFinally) {
  return new Promise((resolve, reject) => {
    this.then(
      (value) => {
        onFinally()
        resolve(value)
      },
      (reason) => {
        onFinally()
        reject(reason)
      }
    )
  })
}
复制代码

Promise.resolve

Promise.resolve(value);
复制代码

Promise.resolve返回一个成功的Promise对象。

参数

  • value

    将被Promise对象解析的参数,也可以是一个Promise对象,或者是一个 thenable对象(拥有 then 方法的对象或者函数)。

返回值

返回一个带着给定值解析过的Promise对象,如果参数本身就是一个Promise对象,则直接返回这个Promise对象。

实现

Promise.resolve = (value) => {
  if (value instanceof Promise) return value
  return new Promise((resolve, reject) => {
    resolve(value)
  })
}
复制代码

Promise.reject

Promise.reject(reason);
复制代码

Promise.reject 返回一个失败的 Promise 对象。

参数

  • reason

    表示Promise失败原因。

返回值

一个失败的 Promise 对象。

实现

Promise.reject = (value) => {
  return new Promise((resolve, reject) => {
    reject(value)
  })
}
复制代码

Promise.all

Promise.all(iterable);
复制代码

Promise.all() 方法接收一个 iterable 类型对象,返回一个 Promise 对象,输入的所有 promise 的成功回调的结果是一个数组

当输入的迭代对象中的 promise 都成功或者迭代对象里没有 promise 了之后,才执行这个Promise成功回调。

其中只要有一个 promise失败,或者输入了不合法的 promise 就会就会立即抛出错误,以第一个抛出的错误信息作为失败的原因。

参数

  • iterable

    一个可迭代对象,如ArrayString

返回值

  • 如果传入的参数是一个空的可迭代对象如 [],则返回一个成功状态的 Promisevalue[]

  • 如果传入的参数不包含任何 promise,返回一个成功状态的 Promisevalue[]

  • 其它情况下返回一个 Pending 状态的 Promise 对象。返回值将会按照参数内的 promise 顺序排列。

实现

// 实现一个 isIterator 函数,用来判断一个对象是否是可迭代的。
const isIterator = (value) => typeof value?.[Symbol.iterator] === 'function'

Promise.all = (iterable) => {
  return new Promise((resolve, reject) => {
    if (!isIterator(iterable)) {
      reject(new TypeError('Promise.all accepts an iterable object'))
      return
    }
    if (iterable.length === 0) {
      resolve([])
      return
    }

    let currentIndex = 0
    const results = []

    const processResult = (index, value) => {
      currentIndex++
      results[index] = value
      if (results.length === iterable.length) resolve(results)
    }

    for (let iterator of iterable) {
      if (!(iterator instanceof Promise)) {
        processResult(currentIndex, iterator)
        continue
      }
      iterator.then(
        (value) => {
          processResult(currentIndex, value)
        },
        (reason) => {
          reject(reason)
        }
      )
    }
  })
}
复制代码

Promise.allSettled

Promise.allSettled(iterable);
复制代码

参数

  • iterable

    一个可迭代对象,如ArrayString

返回值

一个对象数组,包含原始 promises 中的每个结果。

对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason 。value(或 reason )反映了每个 promise 成功或者失败的值。

实现

Promise.allSettled = function (iterable) {
  return new Promise((resolve, reject) => {
    if (!isIterator(iterable)) {
      reject(new TypeError('Promise.allSettled accepts an iterable object'))
      return
    }
    if (iterable.length === 0) {
      resolve([])
      return
    }
    let currentIndex = 0
    const results = []
    const processResult = (index, value) => {
      currentIndex++
      results[index] = value
      if (results.length === iterable.length) resolve(results)
    }

    for (let iterator of iterable) {
      if (!(iterator instanceof Promise)) {
        processResult(currentIndex, { status: 'fulfilled', value: iterator })
        continue
      }
      iterator.then(
        (value) => {
          processResult(currentIndex, { status: 'fulfilled', value })
        },
        (reason) => {
          processResult(currentIndex, { status: 'rejected', reason })
        }
      )
    }
  })
}

复制代码

Promise.race

Promise.race(iterable);
复制代码

Promise.race 函数返回第一个成功或者失败状态的 Promise对象。

如果传的迭代是空的,则返回的 Promise 对象将永远为 Pending 状态。

参数

  • iterable

    一个可迭代对象,如ArrayString

返回值

一个 Pending 状态的 Promise,只要传入的迭代中的其中一个 Promise 变为成功或者失败状态,就用它作为返回的 Promise,从而异步(堆栈为空)地执行Promise回调。

实现

Promise.race = function (iterable) {
  return new Promise((resolve, reject) => {
    if (!isIterator(iterable)) {
      reject(new TypeError('Promise.allSettled accepts an iterable object'))
      return
    }
    for (let iterator of iterable) {
      if (!(iterator instanceof Promise)) {
        resolve(iterator)
        continue
      }
      iterator.then(resolve, reject)
    }
  })
}
复制代码

总结

ok,都写完了。有啥问题可以评论区交流~

分类:
前端
收藏成功!
已添加到「」, 点击更改