Promise主要方法实现

Promise主要方法实现

1. Promise.all

Promise.all用于将多个Promise实例包装成一个Promise实例并返回这个Promise实例,只有所有的promise的状态变为resolved,返回的promise状态才变为resolved,否则变为rejected。

Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    const arr = [...promises]
    const result = []
    let index = 0
    function processData (i, value) {
      result[i] = value
      if (++index === arr.length) {
        resolve(result)
      }
    }
    for (let i = 0; i < arr.length; i++) {
      const p = arr[i]
      if (p && typeof p.then === 'function') {
        p.then(value => {
          processData(i, value)
        }, reject)
      } else {
        processData(i, p)
      }
    }
  })
}

2. Promise.race

返回一个promise,只要有一个状态改变了,就采用它的状态

Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    for (const p of promises) {
      if (p && typeof p.then === 'function') {
        p.then(resolve, reject)
      } else {
        resolve(p)
      }
    }
  })
}
// 取消一个promise的状态
function wrap (p) {
  let abort
  const p1 = new Promise((resolve, reject) => {
    abort = reject // 通过引用把它的reject方法传递出去(闭包)
  })
  const p2 = Promise.race([p1, p])
  p2.abort = abort
  return p2
}
const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 3000)
})
const p1 = wrap(p)
p1.then(res => {
  console.log('success', res)
}).catch(err => {
  console.log('fail', err)
})
setTimeout(() => {
  p1.abort('timeout')
}, 1000)

3. Promise.prototype.finally

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作;
finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

Promise.prototype.finally = function (callback) {
  callback = typeof callback === 'function' ? callback : () => {}
  return this.then(value => {
    Promise.resolve(callback()).then(() => value)
  }, err => {
    Promise.resolve(callback()).then(() => { throw err })
  })
}

const p = new Promise((resolve, reject) => {
  resolve(1)
})
p.finally(() => {
  hello
}).catch(err => {
  console.log(err)
})

4. Promise.allSettled

Promise.allSettled()方法接受一组Promise实例作为参数,包装成一个新的Promise实例。只有等到所有这些实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束
Promise.allSettled()返回的Promise对象的状态总是fulfilled,不会变为rejected

Promise.allSettled = function (promises) {
  return new Promise((resolve, reject) => {
    const arr = Array.from(promises)
    let index = 0
    let result = []
    function setData (i, value) {
      result[i] = value
      if (++index === arr.length) {
        resolve(result)
      }
    }

    for (let i = 0; i < arr.length; i++) {
      const p = arr[i]
      if (p && typeof p.then === 'function') {
        p.then(value => {
          setData(i, {
            value,
            status: 'fulfilled'
          })
        }, err => {
          setData(i, {
            reason: err,
            status: 'rejected'
          })
        })
      } else {
        setData(i, {
          value: p,
          status: 'fulfilled'
        })
      }
    }
  })
}

const p1 = Promise.allSettled([Promise.resolve(1), 2, Promise.reject(3)])
console.log(p1)
p1.then(res => {
  console.log(res)
})

5. Promise.any

ES2021引入了Promise.any()方法。该方法接收一组Promise实例作为参数,包装成一个Promise实例。只要参数实例有一个变为fulfilled,包装实例就会变成fulfilled状态;如果所有参数都变为rejected状态,包装实例就会变成rejected状态。

Promise.any = function (promises) {
  return new Promise((resolve, reject) => {
    let arr = Array.from(promises)
    let errorResult = new Array() // AggregateError
    let index = 0
    function processData(i, value) {
      errorResult[i] = new Error(value)
      if (++index === arr.length) {
        reject(errorResult) // AggregateError: All promises were rejected
      }
    }
    for (let i = 0; i < arr.length; i++) {
      const p = arr[i]
      if (p && typeof p.then === 'function') {
        p.then(resolve, err => {
          console.log(i, err)
          processData(i, err)
        })
      } else {
        resolve(p)
      }
    }
  }) 
}

Promise.any([Promise.reject(-1), Promise.reject(1), Promise.reject(-2)]).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值