首页 > 其他分享 >记录 Promise 的方法

记录 Promise 的方法

时间:2023-04-13 14:46:23浏览次数:48  
标签:resolve const 记录 对象 fulfilled Promise reject 方法

Promise 是异步编程的一种解决方案,比传统的回调函数或事件更合理和更灵活。

Promise 方法

Promise的原型方法:then/catch/finally,这三种方法很常用,then用于处理Promise转为fulfilled状态时的代码,catch用于处理Promise转为rejected状态时的代码(当然then的第二个参数也可处理rejected状态,为了书写在catch中处理),而finally用于不管Promise状态怎样转换都会最终执行的代码。

Promise的静态方法: Promise.all、Promise.allSettled、Promise.any、Promise.race、Promise.resolve、Promise.reject。Promise.resolve和Promise.reject用于一开始就创建 fulfilledrejected状态,其他的静态方法传参是Promise实例数组,差异在于处理实例数组方式和结果。

Promise 静态方法

Promise.all

并行执行多个Promise对象,并在所有Promise对象都成功时返回一个新的Promise对象,其resolve值为一个包含所有Promise结果的数组,如果其中一个Promise对象失败,则返回一个reject的Promise对象,其值为第一个失败的Promise的reject值

;(async () => {
  const promise1 = Promise.resolve('Hello')
  const promise2 = 42
  // const promise2 = Promise.reject('Error')
  const promise3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'Goodbye')
  })
  // const promise4 = Promise.reject('Error2')

  try {
    const result = await Promise.all([promise1, promise2, promise3])
    // 成功输出:[ 'Hello', 42, 'Goodbye' ]
    console.log(result)
  } catch (e) {
    // 失败输出:Error
    console.log(e)
  }
})()

Promise.allSettled

并行执行多个Promise对象,返回一个新的Promise对象(状态一定是fulfilled),其resolve值为一个包含所有Promise结果的数组,其中每个元素都是对象,包含Promise对象的状态和结果

;(async () => {
  const promise1 = Promise.resolve('Hello')
  const promise2 = 42
  // const promise2 = Promise.reject('Error')
  const promise3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'Goodbye')
  })
  // const promise4 = Promise.reject('Error2')

  try {
    const result = await Promise.allSettled([promise1, promise2, promise3])
    // 成功输出:
    // [
    //   { status: 'fulfilled', value: 'Hello' },
    //   { status: 'fulfilled', value: 42 },
    //   { status: 'fulfilled', value: 'Goodbye' }
    // ]
    console.log(result)
    // 失败输出:
    // [
    //   { status: 'fulfilled', value: 'Hello' },
    //   { status: 'rejected', reason: 'Error' },
    //   { status: 'fulfilled', value: 'Goodbye' }
    // ]
  } catch(e) {
    // 不会执行
      console.log('error:', e)
  }

  Promise.allSettled([promise1, promise2, promise3]).then((result) => {
    // 成功输出:
    // [
    //   { status: 'fulfilled', value: 'Hello' },
    //   { status: 'fulfilled', value: 42 },
    //   { status: 'fulfilled', value: 'Goodbye' }
    // ]
    console.log(result)
    // 失败输出:
    // [
    //   { status: 'fulfilled', value: 'Hello' },
    //   { status: 'rejected', reason: 'Error' },
    //   { status: 'fulfilled', value: 'Goodbye' }
    // ]
  })
})()

Promise.all和Promise.allSettled的区别:

  1. Promise.all方法返回的一个Promise对象状态将取决于所有Promise对象的状态。如果其中有任何一个Promise对象被rejected了,那么这个新的Promise对象也会被rejected,并且它的值为第一个被rejected的那个Promise对象的值。
  2. Promise.allSettled方法返回的一个Promise对象状态一定是fulfilled。这个返回的Promise对象的值是一个数组,数组中包含了所有Promise对象的状态和值信息。即便其中有任何一个Promise对象被rejected了,也不会影响这个新的Promise对象的状态。
  3. 错误处理方面,Promise.all只能捕获处理第一个错误状态,如果需要处理所有状态需要改造(如:每个promise设置catch处理、同步请求/异步等待)或者使用 Promise.allSettled,具体需要怎么做看自己的需求

Promise.any

并行执行多个Promise对象,并返回一个新的Promise对象,其resolve值为第一个成功的Promise对象的resolve值,如果所有Promise对象都失败,则返回一个reject的Promise对象,其值为一个AggregateError对象,其中包含所有Promise对象的reject值。

const promise1 = Promise.reject("error1")
const promise2 = Promise.reject("error2")
const promise3 = Promise.resolve("success")
// const promise3 = Promise.reject("error3")

Promise.any([promise1, promise2, promise3]).then((value) => {
  // 成功输出:success
  console.log(value)
}).catch((error) => {
  // 失败输出:
  // [AggregateError: All promises were rejected] {
  //   [errors]: [ 'error1', 'error2', 'error3' ]
  // }
  console.log(error)
})

Promise.race

并行执行多个Promise对象,并返回一个新的Promise对象,其resolve值为第一个完成的Promise对象的resolve值,如果所有Promise对象都失败,则返回一个reject的Promise对象,其值为第一个失败的Promise的reject值。

const promise1 = Promise.reject("error1")
const promise2 = Promise.reject("error2")
const promise3 = Promise.resolve("success")
// const promise3 = Promise.reject("error3")

Promise.race([promise1, promise2, promise3]).then((value) => {
  // 成功输出:error1
  console.log(value)
}).catch((error) => {
  // 失败输出:error1
  console.log(error)
})

Promise.race和Promise.any的区别:

  1. Promise.race会在其中任意一个Promise对象状态改变(即fulfilled或rejected)时立即返回结果,而Promise.any只会在其中任意一个Promise对象fulfilled时返回结果。

  2. 当所有Promise对象都被rejected时,Promise.race会返回被rejected的Promise对象的结果,而Promise.any会抛出AggregateError异常。

  3. 如果Promise.race传入的参数是空数组,它会一直处于pending状态,而Promise.any会立即抛出AggregateError异常。(另外:Promise.all和Promise.allSettled返回fulfilled状态)

使用Promise实现站点预检

这是前几天实现的站点预检:判断所有网站链接是否有效,并返回测试的结果。思路:通过get请求测试,考虑请求之间没有关联、错误处理方面最终选择Promise.allSettled,代码如下:

// 实现 对多个网站链接预检,判定网站链接是否有效

import { get } from 'https'
import { get as getHttp } from 'http'
import { URL } from 'url'

import { ATagSites } from '@/type'

export const detectSitesValid = (allSites: ATagSites[]) => {
  // 遍历 allSites 数组,获取所有网站的链接
  const sites: { name: string; url: string }[] = []
  allSites.forEach((aTagSites) => {
    aTagSites.sites.forEach((site) => {
      sites.push({
        name: site.name,
        url: site.link
      })
    })
  })

  // 存储所有网站的请求
  const fetchRequests: Promise<string>[] = []
  // 存储请求结果
  const fetchResults: string[] = []

  // 遍历所有网站,发起请求
  sites.forEach((site) => {
    const { name, url } = site
    const { protocol } = new URL(url)
    const request = protocol === 'https:' ? get : getHttp
    fetchRequests.push(
      new Promise((resolve, reject) => {
        request(
          {
            hostname: new URL(url).hostname,
            path: new URL(url).pathname,
            method: 'GET',
            timeout: 30000
          },
          (res) => {
            const { statusCode, statusMessage } = res
            fetchResults.push(`${name}, ${url}, ${statusCode || 200}, ${statusMessage || 'OK'}`)
            resolve('ok')
          }
        ).on('error', (err) => {
          const { message } = err
          fetchResults.push(`${name}, ${url}, ${0}, ${message}`)
          resolve('error')
        })
      })
    )
  })

  return Promise.allSettled(fetchRequests)
}

参考

标签:resolve,const,记录,对象,fulfilled,Promise,reject,方法
From: https://www.cnblogs.com/chenmijiang/p/17314754.html

相关文章

  • ubuntu使用记录(5)ubuntu20.04 切换root用户
    ubuntu20.04使用root用户登录系统以普通用户登录系统,创建root用户的密码在终端输入命令:sudopasswdroot先输入当前普通用户(如用户coco)的密码,用于提权。......
  • WPF 自定义控件 二次渲染 问题记录
    问题将多个自定义控件加载到到一个页面的Grid上显示。然后突然将一个控件从Grid里面清除,控件依然在后台处理数据。过段时间再加入Grid。然后一些已经改变的页面属性就消失了。原因经过查找是一旦控件再次加载,页面属性就会重置。这个有利也有弊端。1是可以利用这点重置页面2......
  • flomo 窗口置顶 - 通用方法 autohotkey
    需求开网页的时候需要记录一些东西想一直显示操作要安装https://www.autohotkey.com/创建个.ahk文件运行下快捷键是alt+小键盘8;置顶当前窗口!Numpad8::winset,AlwaysOnTop,,AReturn使用打开flomo为当前激活,然后按快捷键即可。......
  • C#--TextBox的四种禁止编辑方法
    前言一般而言,Textbox中有两个属性可以对其进行防止编辑的设定,这是最基础的知识,也是我要提出的前两种方法。而后两种方法实际为一种,但可以应用于不同环境中。一、ReadOnly属性这样设置,Textbox控件则限制不能输入,但可以读取已有文本,样式也与正常使用的Textbox一致。1、在前端设......
  • 一种分布式鲁棒优化的微电网单元分配方法 python源代码,针对电网负荷和电力市场价格不
    一种分布式鲁棒优化的微电网单元分配方法python源代码,代码按照高水平文章复现,保证正确针对电网负荷和电力市场价格不确定的情况,提出了一种分布式鲁棒单元承诺方法。提出的关键推力的方法是利用Kullback-Leibler分歧概率分布和制定一个优化问题,最小化预期成本所带来的最坏的分......
  • 电网经济和频率控制的多层,多时间尺度模型方法 Julia源代码,代码按照高水平文章复现
    电网经济和频率控制的多层,多时间尺度模型方法Julia源代码,代码按照高水平文章复现,保证正确,可先发您文章看是否满足您的要求由于分散的可再生能源和存储的不断增加,电力系统受到根本性变化的影响。系统中新参与者的去中心化本质要求构建电网的新概念,并实现从几秒到几天的广泛控制......
  • MacOS下强行运行任何来源的APP的方法
    1、首先在电脑左上方点击“系统偏好设置”2、点击“安全性与隐私”按钮。3、勾选“任何来源”按钮,打开即可。   有时候这个选项会不存在,那么需要关闭系统的Gatekeeper,在终端中使用此命令打开:sudospctl--master-disable执行上述步骤之后,出现“任何来源”选项......
  • 带补偿和电力市场上升问题的二元平衡问题的精确求解方法 二元策略中的纳什均衡
    带补偿和电力市场上升问题的二元平衡问题的精确求解方法二元策略中的纳什均衡GAMS源代码,代码按照高水平文章复现,保证正确纳什均衡在游戏中与二元决策变量包括薪酬支付和激励相容约束的非合作博弈理论直接转化为一个优化框架代替使用一阶线性化的条件,或放松的完整性的条件。重......
  • 做价值投资要有正确的方法和坚定的信念
    周五,沪深两市维持震荡走势,今年以来A股市场出现了连续回调,特别是去年涨幅较大的一些赛道股,在获利回吐的压力之下出现较大幅度下跌,而低估值蓝筹股则逆势反弹,市场的风格如期切换。在去年年底我提出2022年A股市场将是价值投资的大年,业绩为王是主要的投资思路,A股一开年就体现了这种风......
  • 让 Spartacus 服务器端渲染引入 long API 调用超时机制的两种配置方法
    两种方法,使用config.backend.timeout={浏览器:...,服务器:...},或者可以更具体地配置,即基于Request粒度,通过将HTTP_TIMEOUT_CONFIGHttpContextToken传递给AngularHttpClient的方法来针对每个具体请求进行配置。在SSR(Node.js)中,超时处理耗时过长的外部http调用是一项尤为重......