# promise 手写 Base on Promise

# promise.all

function PromiseAll(promises){
    return new Promise((resolve, reject)=>{
        if(!Array.isArray(promises)){
            throw new TypeError("promises must be an array")
        }
        let result = []
        let count = 0
        promises.forEach((promise, index) => {
            promise.then((res)=>{
                result[index] = res
                count++
                count === promises.length && resolve(result)
            }, (err)=>{
                reject(err)
            })
        })
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# promise.finally

Promise.prototype.finally = function (cb) {
  return this.then(function (value) {
    return Promise.resolve(cb()).then(function () {
      return value
    })
  }, function (err) {
    return Promise.resolve(cb()).then(function () {
      throw err
    })
  })
}
1
2
3
4
5
6
7
8
9
10
11

# promise.allSettled

function allSettled(promises) {
  if (promises.length === 0) return Promise.resolve([])

  const _promises = promises.map(
    item => item instanceof Promise ? item : Promise.resolve(item)
    )

  return new Promise((resolve, reject) => {
    const result = []
    let unSettledPromiseCount = _promises.length

    _promises.forEach((promise, index) => {
      promise.then((value) => {
        result[index] = {
          status: 'fulfilled',
          value
        }

        unSettledPromiseCount -= 1
        // resolve after all are settled
        if (unSettledPromiseCount === 0) {
          resolve(result)
        }
      }, (reason) => {
        result[index] = {
          status: 'rejected',
          reason
        }

        unSettledPromiseCount -= 1
        // resolve after all are settled
        if (unSettledPromiseCount === 0) {
          resolve(result)
        }
      })
    })
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# promise.race

Promise.race = function(promiseArr) {
    return new Promise((resolve, reject) => {
        promiseArr.forEach(p => {
            Promise.resolve(p).then(val => {
                resolve(val)
            }, err => {
                rejecte(err)
            })
        })
    })
}
1
2
3
4
5
6
7
8
9
10
11

# promise.any

Promise.any = function(promiseArr) {
    let index = 0
    return new Promise((resolve, reject) => {
        if (promiseArr.length === 0) return 
        promiseArr.forEach((p, i) => {
            Promise.resolve(p).then(val => {
                resolve(val)

            }, err => {
                index++
                if (index === promiseArr.length) {
                  reject(new AggregateError('All promises were rejected'))
                }
            })
        })
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# resolve

Promise.resolve = function(value) {
    if(value instanceof Promise){
        return value
    }
    return new Promise(resolve => resolve(value))
}
1
2
3
4
5
6

# rejecte

Promise.reject = function(reason) {
    return new Promise((resolve, reject) => reject(reason))
}
1
2
3