为什么会出现promise
在promise 没有出现之前,写回调函数解决异步的时候,会出现回调地狱的问题。为了解决这个痛点,设计出了promise。
promise的概念
promise是一个对象,用来表示一个异步操作的 最终完成(或失败)以及其结果值。
promise的状态
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
接下来解释一下这三种状态。

打印结果:pending状态和返回结果为undefined


打印结果:fulfilled状态和返回结果为 ""(resolve传入的值)


打印结果:rejected状态和返回结果为 "失败了"(reject传入的值)

如果Executor 函数中,同时调用resolve 和reject呢




结论:Executor 中同时调用两个回调函数,只会生效一个。promise 的状态只能从待定pending 状态变为已兑现fulfilled 或者从待定pending 状态变为已拒绝rejected。
解释:promise 构造函数中,需要传入一个回调函数()=>{},这个函数称为 Promise 执行器(Executor)函数。
Promise 执行器(Executor)的核心特点:
- 强制参数与固定形参 **Promise** 构造函数的参数是 "必须传入" 的函数(若不传入会报错),且该函数有两个固定的、由 JavaScript 引擎提供的形参 **resolve**:调用后会将 Promise 状态从pending(等待)改为 fulfilled(已兑现),并传递 "成功结果"。 **reject**:调用后会将 Promise 状态从pending 改为rejected(已拒绝),并传递 "失败原因"(通常是 Error 对象)。

- 同步执行特性 \ 与 Promise 的 回调(微任务,异步执行)不同,Executor 函数会在创建 Promise 对象时 "立即同步执行"。

- 唯一职责
Executor 的核心作用是 "封装异步操作逻辑",并通过调用resolve 或 reject 来 "决定 Promise 的最终状态"。(白话文解释:就像你让快递小哥(Executor)去送个货(异步操作),他送完了会告诉你 "送到了"(resolve),或者 "弄丢了"(reject),你(Promise)就知道这事儿到底成没成。至于送快递走哪条路线,先送王大妈的还是李大爷的,你(Promise)不关心。)
promise的使用
下面说说执行resolve或reject之后,会发生什么?
当调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数。当调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数。(白话文说就是:Promise就像是容器,里面装着你可能现在要做的事情、也可能以后要做的事情。
- resolve () 一调用,then () 里的代码就跑。
- reject () 一调用,catch () 里的代码就跑 。)
代码注明:

等价:

打印结果:先看是不是promise,然后找resolve和reject。先找到谁,就先看谁,上面是先找到reject,然后就去找catch()

resolve回调函数参数的处理
- resolve传入一个普通的值或者一个对象,这个值会作为then回调的参数

- resolve中传入的是另一个promise,后面的(p) promise会决定前面的 (p1)promise的状态,并且后面的promise的resolve或者reject的参数也会传回给前面的promise。(就像是接力赛一样,后面的没把接力棒给你,你无法向前奔跑一样。)

打印结果:p1要等p完成,要等p的结果。p的状态就决定着p1的状态。p本身需要等5秒才能拿到接力棒(结果)。所以打印显示结果就是:p和p1 的状态以及结果是一样的。

5秒后打印结果:5秒后,p得到了它的结果,就将结果转身给了p1。


打印结果:p的状态要等5秒后,p1因为是调用reject(),所以能拿到状态的结果和结果值(注:resolve和reject的区别,resolve要等resolve,reject不需要等下一个reject)。然后err这个promise也要等p的结果。
结论是console.log(err)就等价于reject(p)===新的promise,这个新的promise,要等p这个promise的结果。

5秒后的打印结果:

Promise的.then和.catch方法的调用

打印结果:


打印结果:

结论:这里是同一个promise多次调用then方法和catch方法,每一个方法后面都是会注册一个新的成功回调或者失败回调,当promise最终变成成功时,注册的多个成功回调会依次执行,失败也是如此。
then和catch的返回值
- then
then方法返回 Promise 对象本身,但链式调用中下一个 then的参数是前一个回调的返回值,这是 Promise 设计的便捷之处。


查看then的返回值是不是promise


- catch
catch 的返回值是一个新的 Promise,其状态由 catch回调函数的执行结果决定,这使得它可以无缝地参与 Promise 链式调用。


因为catch之后会返回一个新的promise,这个新的promise的状态是待定(pending)。除非catch后抛出异常,这样才能让下一个catch捕获到。

- finally
finally是ES9中新增的一个特性,无论promise变成fullfilled状态还是rejected状态,都会执行finally里面的回调,而且finally不接收任何参数。


promise的类方法
Promise.all
`Promise.all` 是 JavaScript 中处理多个异步操作的静态方法,接收一个可迭代对象(通常是 Promise 数组)作为参数,返回一个新的 Promise 对象。其行为特征如下:
- 当所有输入的 Promise 都变为 fulfilled 状态时,返回的 Promise 才会 fulfilled,结果是一个数组,包含所有 Promise 的返回值,且顺序与输入数组保持一致。
- 当任何一个输入的 Promise 变为 rejected 状态时,返回的 Promise 会立即 rejected,且原因是第一个被拒绝的 Promise 的错误信息。
- 适用于需要等待多个独立异步操作全部完成后再执行后续逻辑的场景,具有并行执行特性,能提高异步操作的处理效率。
- 所有都成功了才是成功,一旦有一个失败,就是失败了。


当全部成功时

2秒后打印结果:取最长的任务的时间。顺序和传入的顺序一样。

Promise.resolve
`Promise.resolve` 是 JavaScript 中 Promise 对象的静态方法,用于快速创建一个已处于 fulfilled(成功)状态的 Promise 对象。其行为特征如下:
- 接收一个参数(可以是普通值、Promise 对象或具有 then 方法的对象),返回一个新的 Promise 实例。
- 若参数是 Promise 对象,则直接返回该对象,不做包装。
- 若参数是具有 then 方法的对象(即 "thenable" 对象),会将其转换为 Promise 并执行其 then 方法。
- 若参数是普通值(或无参数),则返回一个以该值为成功结果的 fulfilled 状态 Promise。
- 主要用于将非 Promise 值转换为 Promise 对象,统一异步操作的处理方式。
- 换句话来说,就是不管你给我什么,我都给你一个标准的已经成功的promise
Promise.reject
`Promise.reject` 是 JavaScript 中 Promise 对象的静态方法,用于快速创建一个已处于 rejected(失败)状态的 Promise 对象。其核心特性如下:
- 接收一个参数(通常是错误信息)作为拒绝原因,返回一个新的 Promise 实例。
- 无论传入的参数类型是什么(普通值、Promise 对象或其他),都会被直接作为拒绝原因,不会像Promise.resolve那样对 Promise 参数进行特殊处理。
- 生成的 Promise 会立即进入 rejected 状态,触发后续的catch回调或then方法的第二个参数(错误处理函数)。
- 主要用于统一创建失败状态的 Promise,标准化异步错误的处理方式。
- 换句话来说,就是不管什么情况,我都给你一个标准的已经失败的promise,并且告诉你失败的原因


Promise.race
`Promise.race` 是 JavaScript 中 Promise 对象的静态方法,用于处理多个异步操作的 "竞争" 场景。其核心特性如下:
- 接收一个可迭代对象(通常是 Promise 数组)作为参数,返回一个新的 Promise 对象。
- 当输入的多个 Promise 中任意一个率先改变状态(无论是 fulfilled 成功还是 rejected 失败)时,返回的 Promise 就会立即以相同的状态和结果 / 原因结束。
- 结果仅取决于第一个完成的 Promise,其他后续完成的 Promise 结果会被忽略。
- 适用于需要 "取最快结果" 的场景,例如设置请求超时时间、多个数据源取最快响应等。
- 换句话来说就是,谁快我用谁的结果,不管你是成功还是失败。


Promise.any
`Promise.any` 是 JavaScript 中 Promise 对象的静态方法,用于处理多个异步操作的 "任一成功" 场景。其核心特性如下:
- 接收一个可迭代对象(通常是 Promise 数组)作为参数,返回一个新的 Promise 对象。
- 当输入的多个 Promise 中任意一个变为 fulfilled(成功)状态时,返回的 Promise 会立即以该成功结果结束。
- 只有当所有输入的 Promise 都变为 rejected(失败)状态时,返回的 Promise 才会 rejected,此时错误信息是一个包含所有失败原因的对象。
- 适用于 "多个备选方案取第一个成功结果" 的场景,例如多源数据加载(只要一个数据源成功即可)。
- 换句话说,多个结果,我就等第一个成功的结果。但是都是失败了,我才去找失败的原因。这里就拿返回的AggregateError对象查看原因。

Promise.allSettled
`Promise.allSettled` 是 JavaScript 中 Promise 对象的静态方法,用于处理多个异步操作的 "完整结果收集" 场景。其核心特性如下:
- 接收一个可迭代对象(通常是 Promise 数组)作为参数,返回一个新的 Promise 对象。
- 只有当所有输入的 Promise 都已 "落定"(即状态变为 fulfilled 成功或 rejected 失败)时,返回的 Promise 才会变为 fulfilled 状态。
- 结果是一个数组,其中每个元素对应输入 Promise 的结果:成功的结果包含status: "fulfilled" 、status: "rejected" 和reason字段
- 适用于需要获取所有异步操作的完整结果(无论成功或失败)的场景,例如批量任务执行后的全面统计或日志记录。
- 换句话来说:就是等所有的promise都有了结果(不论成功或者失败),结果数组和输入的时候一致。就像一个团队组织三个项目,不论项目成功还是失败了都要汇报一样。
- 多个任务同时进行,不着急,等所有人都有结果了(不管好坏),再把所有结果汇总给你,让你知道每个任务的具体情况。
\
总结:
Promise对一理解异步编程,至关重要。理解Promise对于一个前端开发者来说是必修课。不然你遇到问题,总是采用试错的方法解决问题,这样是不行的。一直以来我对promise的了解,一直停留在promise是回调地狱的解决办法。很多次我都想要了解promise,但是看看文档就不想看了,今天算是正式的认识promise吧!💪加油!