JS Promise

Promise是JavaScript的异步操作解决方案,它比起其它方式,比如说回调,要好很多,通过把异步任务抽象成模型,再把这个模型封装成一个对象,就是Promise对象。

所有的异步任务,都可以抽象成这么一个模型:

  1. 这个任务有两个阶段:未决阶段、已决阶段。
  2. 这个任务有三个状态:挂载状态、完成状态、失败状态。未决阶段有挂载状态,已决阶段有完成状态和失败状态。
  3. 这个任务有两个后续处理:完成状态后续处理、失败状态后续处理。

满足上述三点的任务,就叫它异步任务。

如何用Promise对象模拟出异步任务的这些特征呢?

下面从Promise对象的创建和使用两个方面来介绍一下。

Promise的创建

ES6为我们提供了一个构造函数Promise,专门用来创建Promise对象。

js 复制代码
new Promise((resolve,reject)=>{
    setTimeout(() => {
        resolve('data');
  }, 300);
})

构造函数的参数是一个执行器函数,它会在创建Promise对象时立即执行。

同时执行器函数会接收两个函数作为参数,第一个参数被调用,该任务进入完成状态,如果有链式调用还会进入完成状态后续处理,第二个参数被调用,该任务进入失败状态,如果有链式调用也会进入失败状态后续处理。

Promise的使用

Promise的主要使用方式是用它提供的实例和静态方法。

一 实例方法
  • then()

    可以接受两个参数,且是可选的,作为 promise 兑现和拒绝情况的回调函数,有then(onFulfilled)和then(onFulfilled, onRejected)两种调用方式。

    onFulfilled函数的参数是前一个promise的兑现值,onRejected函数的参数是前一个promise的拒绝值。

    ps:如果 onFulfilled 不是一个函数,则内部会被替换为一个恒等函数((x) => x),如果 onRejected 不是一个函数,则内部会被替换为一个抛出器函数((x) => { throw x; })。

    then()会返回一个等效的Promise对象,新的promise的行为(称为p)取决于处理函数的执行结果,如果处理函数:

    1. 返回一个值:p 以该返回值作为其兑现值。
    2. 没有返回任何值:p 以 undefined 作为其兑现值。
    3. 抛出一个错误:p 抛出的错误作为其拒绝值。
    4. 返回一个已兑现的 Promise 对象:p 以该 Promise 的值作为其兑现值。
    5. 返回一个已拒绝的 Promise 对象:p 以该 Promise 的值作为其拒绝值。
    6. 返回另一个待定的 Promise 对象:p 保持待定状态,并在该 Promise 对象被兑现/拒绝后立即以该 Promise 的值作为其兑现/拒绝值。
  • catch()

    接受一个参数,作为在 promise 被拒绝时的回调函数,使用方式是catch(onRejected),这是then(null, onRejected) 的一种简写形式。

    onRejected函数的参数是前一个promise的拒绝值。

    返回一个等效的Promise对象,新的promise的行为(称为p)取决于是否调用了onRejected 处理函数以及该函数的返回值:

    1. 如果 onRejected 没被调用(前一个 promise 已兑现),返回的 promise 与前一个 promise 具有相同的兑现值。
    2. 如果调用了 onRejected 处理函数(前一个 promise 已拒绝),则返回的 promise 将根据此调用的返回值进行兑现,或者使用此调用引发的错误进行拒绝。
  • finally()

    接受一个参数,作为在 promise 敲定时(兑现或拒绝)的回调函数,使用方式是finally(onFinally)。

    onFinally函数无参数。

    返回一个等效的Promise对象,新的promise的行为(称为p)取决于 onFinally 处理函数的执行结果:

    1. 如果 onFinally 抛出错误或返回被拒绝的 promise,则新的 promise 将使用该值进行拒绝。
    2. 否则,新的 promise 将与前一个 promise 以相同的状态敲定。
二 静态方法
  • Promise.all()

    接受一个 Promise 可迭代对象作为输入,并返回一个 Promise。

    当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。

  • Promise.allSettled()

    将一个 Promise 可迭代对象作为输入,并返回一个单独的 Promise。

    当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

  • Promise.any()

    将一个 Promise 可迭代对象作为输入,并返回一个 Promise。

    当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateError 拒绝。

  • Promise.race()

    接受一个 promise 可迭代对象作为输入,并返回一个 Promise。

    这个返回的 promise 会随着第一个 promise 的敲定而敲定,并返回第一个敲定的兑现值或者拒绝值。

  • Promise.reject()

    返回一个已拒绝(rejected)的 Promise 对象,拒绝原因为给定的参数。

    即使参数已经是一个 Promise 对象,Promise.reject() 方法也始终会将其封装在一个新的 Promise 对象中。

  • Promise.resolve()

    以给定值"解决(resolve)"一个 Promise。

    如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现。

    ps:在 Promise 成为 JavaScript 语言的一部分之前,JavaScript 生态系统已经有了多种 Promise 实现,它们都实现了 Thenable 接口,thenable 对象实现了 .then() 方法。Promise 也是 thenable 对象。

  • Promise.try()

    接受一个任意类型的回调函数(无论其是同步或异步,返回结果或抛出异常),并将其结果封装成一个 Promise。

    使用方式是Promise.try(func, arg1, arg2, /* ..., */ argN),返回一个 Promise,其状态可以是:

    1. 已兑现的,如果 func 同步地返回一个值。
    2. 已拒绝的,如果 func 同步地抛出一个错误。
    3. 异步兑现或拒绝的,如果 func 返回一个 promise。
  • Promise.withResolvers()

    返回一个对象,其包含一个新的 Promise 对象和两个函数,用于解决或拒绝它,对应于传入给 Promise() 构造函数执行器的两个参数。

总结

Promise是JS中专门用来处理异步任务的对象,针对异步任务的特征,它定义了很多静态和实例方法,解决不同场景下的异步流程。

相关推荐
Fly8 分钟前
我来提需求,你带着 Codex 做项目:AI 全栈课程开始实战了
前端
集智飞行27 分钟前
解决mavros2 ros2版本cpu占用高的问题
java·服务器·前端
w2sfot1 小时前
【JS加密在线】jsjiami.online(让JavaScript 更安全!)
开发语言·javascript·安全
HSunR1 小时前
ruoyi 若依 自定义注解 参数校验
java·前端·数据库
拆房老料2 小时前
ONLYOFFICE也能像Microsoft Word和WPS一样分别设置中西文字体
前端·html·word·开源软件·wps
Solis程序员3 小时前
Stripe 幂等表:把「不确定的重试」变成「查表返回」
前端·安全·bootstrap·php·agent
李纲明3 小时前
WordPress 站点变慢:按 TTFB → 缓存 → 查询 → 前端 分层排查(含配置注意)
前端·缓存·性能优化·wordpress·后端开发
程序人生8883 小时前
PDF 转 Word 版式错乱、表格丢失?DocConverter Web 格式互转引擎的保真实践
前端·人工智能·opencv·机器学习·pdf·word
粥里有勺糖4 小时前
安利一下最近用的桌面“Agent” | T3 Code
前端·github·ai编程
xy34534 小时前
Axure 9.0 动态面板基本操作
前端·ui·html·axure·原型·产品设计