# promise 的理解

# 什么是 promise,解决什么问题

promise 是异步编程的一种解决方案,用来解决异步操作函数里的多层嵌套回调(即回调地狱)问题。

# 原理(看 promise.js)

创建 Promise 构造函数, 添加 resolve 、reject、then、catch、finally 等方法。Promise 入参是个回调函数,执行回调函数得到的正确结果通过 resolve 方法传送到 then 方法,错误结果通过 reject 方法传送到 catch 方法。因为 Promise 是异步的, 所以需要有异步的方法来执行回调函数。浏览器端,采用的是 window.MutationObserver || setTimeout || setInterval 三个方法来执行异步回调,服务端则采用的是 setImmediate || process.nextTick 来执行回调。总的来说就是采用异步方法去执行入参的回调函数,每一个链式的每一个 then 都会触发一次异步回调。

# 三种状态

  • Fulfilled:Promise 执行成功
  • Rejected:Promise 执行失败
  • Pending:Promise 正在执行中 一个 promise 的状态只可能从 pending 变为 fulfilled ,或者 pending 变为 rejected,不能逆向转换,同时“完成”态和“拒绝”态不能相互转换。

# API 概述

  1. 构造器
let p = new Pomise((resolve, reject) => {
  // resolve(...) 决议/完成
  // reject(...) 用于拒绝这个promise
})
  1. 原型方法 then/catch/finally

  2. 本身方法

  • Promise.all([...]) :按顺序全部执行
  • Promise.race([...]):返回执行最快的一个 promise 结果
  • Promise.resolve()
  • Promise.reject()
  • Promise.finally() ---ES9(2018)
  • Promise.allSettled() ---ES11(2020)
  • Promise.any() ---ES12(2021)

# thenable 对象

  • 定义:具有 then(...)方法的对象和函数
  • 所有的 Promise 都是 thenable 对象,但并非所有 thenable 对象都是 Promise

# 判断是否是 Promise/A+规范

主要看 Promise 方法是否含有 new Promise(function(resolve, reject){})、then、resolve 等方法

# 与 setTimeout 的区别

promise 是微任务,setTimeout 是宏任务,同一个事件循环中,promise.then 总是先于 setTimeout 执行。

# 如何控制 promise 任务的并发数

  • 用 Promise.race 来实现
  • 步骤:先循环把并发池塞满,利用 Promise.race 方法来获得并发池中某任务完成的信号, 每当并发池跑完一个任务,就再塞入一个任务,请求结束后将该 Promise 任务从并发池中 移除,直到全部的请求被取完。

# 实现异步的方法

setTimeout,事件监听,观察者模式,promise,generator,async/await,第三方 async 库