Promise 的作用 
一、概念 
Promise 是 js 中用于异步编程的一种对象。它表示一个异步操作的最终完成(或失败)及其结果值。一个 Promise 对象可以处于以下三种状态之一:
- Pending(进行中):初始状态,既不是成功,也不是失败。
- Fulfilled(已成功):操作成功完成。
- Rejected(已失败):操作失败。
异步编程的情形
- fs 读取文件
- Ajax 请求
- 定时器
- 事件监听
- ...
二、语法 
创建一个 Promise 实例通常涉及提供一个执行器(executor)函数,该函数接受两个参数,分别是 resolve 和 reject:
js
const myPromise = new Promise((resolve, reject) => {
  // 异步操作
  if (/* 操作成功 */) {
    resolve(value);  // 传递成功结果
  } else {
    reject(error);  // 传递错误或失败原因
  }
});三、特点 
- 链式调用:Promise 可以通过 then方法链式调用,每个then返回一个新的 Promise,可以解决回调地狱问题。
- 不可变状态:一旦 Promise 状态变为 Fulfilled 或 Rejected,它将永远保持该状态,不会再变。
- 错误冒泡(异常穿透):类似于同步代码中的异常冒泡,Promise 在链式调用中,如果没有捕获异常,会传递至链尾。
四、常用 API 
- Promise.then(onFulfilled, onRejected):添加成功或失败的回调函数。
- Promise.catch(onRejected):添加一个拒绝(或错误)处理回调,是- then(null, rejection)的别名。
- Promise.finally(onFinally):无论 Promise 最终状态如何,都会执行的处理器。
- Promise.all(iterable):接受一个 Promise 对象的集合,当所有 Promise 都成功时,返回一个成功的新 Promise,包含所有结果。
- Promise.race(iterable):接受一个 Promise 对象的集合,返回一个新 Promise,它由第一个 settled(无论是 fulfilled 还是 rejected)的 Promise 决定。
五、实现原理 
Promise 的实现原理基于以下几个核心概念:
- 回调函数管理:内部维护两个回调列表,一个用于成功的回调,一个用于失败。
- 状态转移:执行器中的 resolve或reject负责状态的转移。
- 微任务队列:Promise 的回调执行是在 js 事件循环的微任务阶段进行的。这意味着 Promise 回调总是在同步代码执行完后才开始执行。
- 异步执行流:利用 js 的事件机制(如 setTimeout,setImmediate, 或process.nextTick)保证then和catch方法异步执行。
六、高级用法 
TODO
七、备注 
1)如何中断 promise 链 
要中断一个 Promise 链,你可以选择抛出一个错误(throw 一个错误),或者返回一个被拒绝(rejected)的 Promise。这将导致链中后续的 .then 或 .catch 块被跳过,直到捕获到一个错误处理函数。
js
Promise.resolve()
  .then(() => {
    throw new Error('Something went wrong!')
  })
  .then(() => {
    console.log('This will not run')
  })
  .catch((error) => {
    console.log('Error caught:', error.message)
  })在实践中,有时也可以通过返回一个永远不会解决或拒绝的 Promise 来“暂停” Promise 链,从而实现类似中断的效果:
js
new Promise(() => {}) // 永远不解决的 Promise
  .then(() => console.log('This will not run'))js
let p = new Promise((resolve, reject) => resolve(1111))
p.then(() => {
  console.log('This will run')
  return new Promise(() => {}) 
})
  .catch(() => console.log('This will not run'))
  .finally(() => console.log('This will not run'))2)async/await 的作用 
async 和 await 是使异步代码看起来和同步代码类似的语法糖。async 函数声明该函数是异步的,并且其内部可以使用 await 来等待异步操作的结果,而不会阻塞函数外的代码执行。这样可以写出更加清晰、易于维护的异步代码。
js
async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data') 
    const data = await response.json()
    console.log(data)
  } catch (error) {
    console.error('Error:', error)
  }
}这种方式使得错误处理变得简单,可以用传统的 try/catch 结构来捕捉异步操作中的错误。
3)throw 抛出异常改变状态 
在 Promise 中,使用 throw 可以将 Promise 的状态从 "fulfilled" 改变为 "rejected"。这意味着你可以用 throw 在函数中直接触发错误处理逻辑,而这通常用在 .then 方法中。被 throw 抛出的异常会被 Promise 链中最近的 .catch 块捕获。
js
Promise.resolve()
  .then(() => {
    throw new Error('Failed here!')
  })
  .catch((error) => {
    console.error('Caught an error:', error.message)
  })在 async 函数中,抛出异常将导致 Promise 被拒绝,这个异常可以在调用该异步函数的地方被 .catch 方法捕获。
js
async function mightFail() {
  throw new Error('Something went wrong!')
}
mightFail().catch((error) => {
  console.log('Error:', error.message)
})