# Promise.finally()

  • finally() 方法返回一个 Promise 。在 promise 结束时,无论结果是 fulfilled 或者是 rejected,都会执行指定的回调函数。

  • 这为在 Promise 是否成功完成后都需要执行的代码提供了一种方式。

    这避免了同样的语句需要在 then() catch() 中各写一次的情况。

  • 如果你想在 promise 执行完毕后无论其结果怎样都做一些处理或清理时, finally() 方法可能是有用的。

# resolve 结束会执行 finally

new Promise((resolve, reject) => {
  resolve('resolve 233')
})
.then(res => {
  console.log(res) // resolve 233
})
.catch(err => {
  
})
.finally(() => {
  console.log(`finally code execute`) // finally code execute
})

# reject 结束会也会执行 finally

new Promise((resolve, reject) => {
  reject('reject 233')
})
.then(res => {
  console.log(res) 
})
.catch(err => {
  console.log(err) // reject 233
})
.finally(() => {
  console.log(`finally code execute`) // finally code execute
})

# Promise.resolve()

  • value 将被 Promise 对象解析的参数,也可以是一个 Promise 对象,或者是一个 thenable。
  • 返回一个带着给定值解析过的 Promise 对象,如果参数本身就是一个 Promise 对象,则直接返回这个 Promise 对象。
  • 静态方法 Promise.resolve 返回一个解析过的 Promise 对象。
  • resolve 方法会将里面的参数转成 Promise 返回出去 并且状态默认为 resolve

# 普通值

Promise.resolve({ name: 'Lain' })
.then(res => {
  console.log(res) // {name: 'Lain'}
})

# Promise

Promise.resolve(
  new Promise((resolve, reject) => resolve('Promise resolve'))
)
.then(res => {
  console.log(res) // {name: 'Lain'}
  throw new Error('23333')
})
  .catch(err => {
  // 优先捕获自身状态 -> 是 resolve, 那么捕获 then 返回的 Promise 抛出的错误
  console.log(err) // Error: 23333
})

# thenable

Promise.resolve({
  then: (resolve, reject) => {
    resolve('233')
  }
})
.then(res => {
  console.log(res) // 233
})

# Promise.reject()

  • 无论传入都会把 reject 里面的值 给到 err

# reject 传入普通的值

Promise.reject('rejected 23333')
.catch(err => {
  console.log(err) // rejected 23333
})

# thenable

Promise.reject({
  then: (resolve, reject) => {
    resolve(function foo(){})
  }
})
.catch(err => {
  console.log(err) // { then: [Function: then] }
})

# 传入 promise 也是一样

Promise.reject(new Promise(() => {}))
.catch(err => {
  // 没有使用 resolve 和 reject, 所以状态是 pending
  console.log(err) // Promise { <pending> }
})

# Promise.all()

  • Promise.all 等待所有都完成(或第一个失败)

# 需求:所有的 Promise 都变成 fulfilled 时,再拿到结果

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    resolve('p1 1000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    resolve('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    resolve('p3 3000s')
  }, 3000)
})
Promise.all([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) //  ['p1 1000s', 'p2 2000s', 'p3 3000s', 'Lain']
})
// 结果顺序与传入的顺序有关
Promise.all([p3, p2, p1, 'Saber'])
.then(res => {
  console.log(res) // ['p3 3000s', 'p2 2000s', 'p1 1000s', 'Saber']
})

# 意外:在拿到所有结果之前,有一个 promise 变成了 rejected, 那么整个 promise 是 rejected

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    resolve('p1 1000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    // 修改状态
    reject('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => { 
    resolve('p3 3000s')
  }, 3000)
})
Promise.all([p1, p2, p3])
.then(res => {
  console.log(res)
})
.catch(res => {
  console.log(res)  // 2s 后输出 ->  p2 2000s
})
// 与顺序无关 失败状态就会立即将结果返回出去
Promise.all([p3, p2, p1])
.then(res => {
  console.log(res)
})
.catch(res => {
  console.log(res)  // 2s 后输出 ->  p2 2000s
})

# Promise.allSettled()

  • Promise.allSettled() 方法返回一个在所有给定的 promise 都已经 fulfilledrejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。
  • 当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个 promise 的结果时,通常使用它。
  • 相比之下, Promise.all() 更适合彼此相互依赖或者在其中任何一个 reject 时立即结束。
  • 一旦所指定的 promises 集合中每一个 promise 已经完成,无论是成功的达成或被拒绝,未决议的 Promise 将被异步完成。那时,所返回的 promise 的处理器将传入一个数组作为输入,该数组包含原始 promises 集中每个 promise 的结果。
  • 对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled ,则结果对象上存在一个 value 。如果值为 rejected ,则存在一个 reason 。value(或 reason )反映了每个 promise 决议(或拒绝)的值。

# 状态全部为 fulfilled

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 1000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3 3000s')
  }, 3000)
})
Promise.allSettled([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res)  
})
// 与 all 方法不同的是,allSettled 同样返回一个数组,但是数组中都是对象形式,并保存了他们的状态
 [
  { status: 'fulfilled', value: 'p1 1000s' },
  { status: 'fulfilled', value: 'p2 2000s' },
  { status: 'fulfilled', value: 'p3 3000s' },
  { status: 'fulfilled', value: 'Lain' }     
]

# 某个状态为 rejected

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 1000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p3 3000s')
  }, 3000)
})
Promise.allSettled([p1, p2, p3, 'Saber'])
.then(res => {
  console.log(res)  
})
/* 他们并没有终端 而是全部执行并返回他们的妆台  从下面也能看出
[
  {status: 'fulfilled', value: 'p1 1000s'},
  { status: 'rejected', reason: 'p2 2000s' },
  { status: 'rejected', reason: 'p3 3000s' },
  { status: 'fulfilled', value: 'Saber' }    
]
*/
Promise.allSettled([p3, p2, p1, 'Saber'])
.then(res => {
  console.log(res)  
})
/* 并且结果也是与传入顺序有关 与执行结束顺序无关
[
  {status: 'rejected', reason: 'p3 3000s'},
  { status: 'rejected', reason: 'p2 2000s' },
  { status: 'fulfilled', value: 'p1 1000s' },
  { status: 'fulfilled', value: 'Saber' }
]
*/

强调一点 这两个方法 我传入的第四个参数都是普通的值,但他们都会以Promise形式返回, 类似 Promise.resolve('Saber')

# Promise.race()

  • Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。
  • race 函数返回一个 Promise ,它将与第一个传递的 promise 相同的完成方式被完成。它可以是完成( resolves),也可以是失败(rejects),这要取决于第一个完成的方式是两个中的哪个。

# 状态全部为 fulfilled

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 1000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3 3000s')
  }, 3000)
})
// 'Lain' 没有延时 所以返回的是 Lain
Promise.race([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) // Lain
})
//p1 是最先有结果的 所以会输出 p1 的结果
Promise.race([p1, p2, p3])
.then(res => {
  console.log(res) // p1 1000s
})

# 某个状态为 rejected

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 3000s')
  }, 3000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3 3000s')
  }, 3000)
})
// 'Lain' 没有延时 所以返回的是 Lain
Promise.race([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) // Lain
})
.catch(err => {
  console.log(err)
})
// 虽然 p2 是 reject,但 是最先有结果的 所以依然会输出 p2 的结果
Promise.race([p1, p2, p3])
.then(res => {
  console.log(res) // p1 2000s
})
.catch(err => {
  console.log(err)
})

# Promise.any()

  • 这个方法用于返回第一个成功的 promise 。只要有一个 promise 成功此方法就会终止,它不会等待其他的 promise 全部完成。
  • 不像 Promise.all() 会返回一组完成值那样(resolved values),我们只能得到一个成功值(假设至少有一个 promise 完成)。当我们只需要一个 promise 成功,而不关心是哪一个成功时此方法很有用的。
  • 同时,也不像 Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。这个方法将会忽略掉所有被拒绝的 promise ,直到第一个 promise 成功。

# 状态全部为 fulfilled

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 2000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p2 2000s')
  }, 2000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3 3000s')
  }, 3000)
})
// 'Lain' 没有延时 所以依然返回的是 Lain
Promise.any([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) // Lain
})
// 虽然输入顺序是 p2 优先 但与 all 不同,会按执行顺序输出  那么就是 p1
Promise.any([p2, p1, p3])
.then(res => {
  console.log(res) // p1 2000s
})

# 某个状态为 rejected

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1 2000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2 1000s')
  }, 1000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p3 3000s')
  }, 3000)
})
// 'Lain' 没有延时 所以依然返回的是 Lain
Promise.any([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) // Lain
})
// 虽然 reject 会优先执行, 但 any 与 race 不同, 会等到一个 resolve 才会有对应的结果
Promise.any([p2, p1, p3])
.then(res => {
  console.log(res) // p1 2000s
})

# 状态全部为 rejected

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p1 2000s')
  }, 1000)
})
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p2 1000s')
  }, 1000)
})
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('p3 5000s')
  }, 3000)
})
// Lain 返回的 Promise 默认是 resolve 状态 所以依然返回的是 Lain
Promise.any([p1, p2, p3, 'Lain'])
.then(res => {
  console.log(res) // Lain
})
.catch(err => {
  console.log(err);
})
// 会等失败状态全部执行完才会执行 catch 并返回一个错误:AggregateError: All promises were rejected (所有承诺被拒绝)
Promise.any([p2, p1, p3])
.then(res => {
  console.log(res) 
})
.catch(err => {
  console.log(err) // AggregateError: All promises were rejected (所有承诺被拒绝)
  // 通过 errors 拿到所有失败的错误信息
  console.log(err.errors) // ['p2 1000s', 'p1 2000s', 'p3 5000s']
})