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中专门用来处理异步任务的对象,针对异步任务的特征,它定义了很多静态和实例方法,解决不同场景下的异步流程。

相关推荐
lichenyang4532 小时前
React ajax中的跨域以及代理服务器
前端·react.js·ajax
呆呆的小草2 小时前
Cesium距离测量、角度测量、面积测量
开发语言·前端·javascript
WHOAMI_老猫2 小时前
xss注入遇到转义,html编码绕过了解一哈
javascript·web安全·渗透测试·xss·漏洞原理
一 乐3 小时前
民宿|基于java的民宿推荐系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·源码
testleaf3 小时前
前端面经整理【1】
前端·面试
好了来看下一题3 小时前
使用 React+Vite+Electron 搭建桌面应用
前端·react.js·electron
啃火龙果的兔子3 小时前
前端八股文-react篇
前端·react.js·前端框架
小前端大牛马3 小时前
react中hook和高阶组件的选型
前端·javascript·vue.js
刺客-Andy3 小时前
React第六十二节 Router中 createStaticRouter 的使用详解
前端·javascript·react.js
秋田君4 小时前
深入理解JavaScript设计模式之策略模式
javascript·设计模式·策略模式