记录 Promise 的方法

这篇具有很好参考价值的文章主要介绍了记录 Promise 的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

Promise 方法

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

promise的then方法的第二个参数和catch方法都可以处理rejected状态,但它们之间有一些区别:

  1. then的第二个参数只能处理当前的promise,而catch方法可以处理任意位置的rejected状态。所以,如果多个then方法链式调用中有多个rejected状态,可以在最后使用一个catch方法来处理。

  2. then的第二个参数和catch方法的返回值不同。then的第二个参数返回的是一个新的promise对象,而catch方法返回的是一个值或一个新的promise对象。如果返回的是一个值,则会被自动包装成一个resolved状态的promise。

  3. catch方法比then的第二个参数更简洁,更易读。因为catch方法只处理rejected状态,而then方法需要在第一个参数中同时处理resolved和rejected状态。

Promise的静态方法: Promise.all、Promise.allSettled、Promise.any、Promise.race、Promise.resolve、Promise.reject。

Promise 静态方法

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.allSettled的兼容性,可以利用promise实现:

if (!Promise.allSettled) {
  Promise.allSettled = function (promises) {
    return new Promise((resolve) => {
      const data = [],
        len = promises.length
      let count = len
      for (let i = 0; i < len; i++) {
        const promise = promise[i]
        promise
          .then(
            (res) => {
              data[i] = { status: 'fulfilled', value: res }
            },
            (error) => {
              data[i] = { status: 'rejected', value: error }
            }
          )
          .finally(() => {
            if (i === count) {
              resolve(data)
            }
          })
      }
    })
  }
}

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,代码如下:文章来源地址https://www.toymoban.com/news/detail-412651.html

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

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)
}

参考

  • Promise.all和promise.allSettled的用法,promise.all的错误捕获方法
  • Promise 的实例方法和静态方法有哪些,如何手动实现?

到了这里,关于记录 Promise 的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端异步编程全套:xmlhttprequest > ajax > promise > async/await

    同步与异步区别 同步:按顺序,依次执行,向服务器发送请求--客户端做其他操作 异步:分别执行,向服务器发送请求==同时执行其他操作 原生xmlhttprequest 四步骤 创建ajax对象 设定数据的传输方式(get、post),打开连接open() 获得响应数据 属性 描述 onreadystatechange 当readysta

    2024年02月01日
    浏览(71)
  • 微信小程序异步请求数据promise方法

    在小程序中可以直接使用promise,我们需要做的就是在A函数中返回一个promise,在返回的promise中再进行获取数据的操作,把成功获取到的数据传入resolve中,把失败的结果传入reject,然后在B函数中调用A函数,调用后再使用.then 和 .catch 分别对成功和失败的结果进行处理

    2024年02月06日
    浏览(46)
  • 【angular教程240111】08异步数据流编程与angular :promise,Rxjs6.x

    【angular教程240111】08异步数据流编程与angular :promise,Rxjs6.x 三级目录 异步与 Rxjs6.x异步数据流编程-Angular Rxjs快速入门 一、 Rxjs介绍 二、 Promise和RxJS 处理异步对比 三、 Rxjs unsubscribe取消订阅 四、 Rxjs 订阅后多次执行 五、 Angualr6.x之前使用Rxjs的工具函数map filter 六、 Angualr6

    2024年02月02日
    浏览(44)
  • 记录 Promise 的方法

    Promise 是异步编程的一种解决方案,比传统的回调函数或事件更合理和更灵活。 Promise的原型方法:then/catch/finally,这三种方法很常用, then 用于处理Promise转为 fulfilled 状态时的代码, catch 用于处理Promise转为 rejected 状态时的代码(当然 then 的第二个参数也可处理 rejected 状态

    2023年04月14日
    浏览(32)
  • 【异步系列三】10道 Promise 面试题彻底理解 Promise 异步执行顺序

    上一篇文章详细说明了关于 Promise 的概念以及执行顺序,Promise 作为 JavaScript 中的关键特性,无论是在日常工作中还是面试中,我们都必须掌握它。 前段时间在网上看到了一些关于 Promise 的面试题,质量很好,在这里整理到下面,并加上我一些自己的见解,欢迎斧正! 1. 同步

    2024年02月09日
    浏览(49)
  • 并发编程 --- 异步方法的异常处理

    现在模拟一个异步方法抛出了异常: 思考一下, DontHandle() 方法是否能够捕获到异常? 答案是:不会捕获到异常! 因为 DontHandle() 方法在 ThrowAfter() 方法抛出异常之前,就已经执行完毕。 那么上述代码怎么才能捕获到异常呢? 若想要捕获异常则必须通过 await 等待 Th

    2024年02月15日
    浏览(46)
  • 前端异步技术之Promise

    由于是参(抄)考(袭)前辈的polyfill,自己编码测试时出现了两处错误,ES6 Promise 规范的2.3.1和2.3.4 2.3.1 你们的支持是我最大的动力,熬夜码字不易,如果此文对你有帮助,请不吝star---https://github.com/chenchangyuan/promise 有兴趣加笔者好友的同学请扫描下方二维码(1.本人微信,

    2024年02月08日
    浏览(69)
  • 异步同步化( Promise 详解)

    ES 6 Promise的用法 一 、为什么要使用Promise “ 回调地狱 ”这个词,不知道大家听过没有,就是异步调用 获取到结果 后, 为下一个异步函数提供 参数 ,所以就会一层一层的出现回调里面 嵌入回调,导致层次很深,代码维护起来特别的复杂,看一下下面的小案例大家就知道什

    2024年02月16日
    浏览(47)
  • JS 异步编程方法:6种方案

        javascript语言的执行环境是\\\"单线程\\\"。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,在执行后面一个任务     这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要一个任务耗时很长,后面的任务都必须排队等着,会拖延整

    2023年04月08日
    浏览(38)
  • 常见的异步编程的几种方法

    回调函数 Promise Rxjs 1、回调函数   2、Promise   3、Rxjs 注意:不管是通过 Promise 的 resolve返回,还是通过 getRxjsData 的 observer 返回,返回的时间用户都不能马上得到,必须分别使用 then 和 subscribe 来订阅   4、Rxjs取消订阅   5、rxjs订阅后多次执行  

    2024年01月20日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包