详解JavaScript中Promise类的使用方法

目录
  • 1. all
  • 2.  allSettled
  • 3.  race
  • 4. any

这篇主要讲一下Promise的类方法的基本使用,至于Promise的基本使用这里就不赘述了,之前也有手写过Promise、实现了Promise的核心逻辑。其实我们平时用Promise也挺多的,不过又出现了两个新的语法(ES11,ES12新增了两个),所以这篇就简单说一下,也挺简单

1. all

Promise.all方法我们可以传入一个数组参数,数组中可以放多个Promise,它会等所有的Promise的状态都为fulfilled时,来获取最终的结果,它会把所有每个Promise resolve的结果,放在一个数组中,且结果的顺序和我们传入的数组参数中的Promise保持一直(跟时间无关)

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    resolve(obj)
  }, 2000)
})

const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})

Promise.all([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

上面代码会在3s后在then方法中拿到最终的结果如下:

但是all方法是有个缺陷的,当有其中一个Promise变成rejected状态时,新Promise就会立即变成对应的reject状态,也就是只能在catch中捕获到错误,其他fulfilled状态的值我们是拿不到的。因此有了allSettled方法

2.  allSettled

allSettled是在ES11(2020)中添加的新的API,Promise.allSettled

该方法会在所有的Promise都有结果时(无论是fulfilled,还是rejected)都会在then方法中拿到我们的最终的结果:

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    reject(obj)
  }, 2000)
})

const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})

Promise.allSettled([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

我们传入了三个Promise,在2s的时候我们的p2就reject拒绝了,但是我们同样可以拿到结果,但是这个result结果数组结构有点儿变化,我们看下打印结果:

我们可以看到allSettled的结果是一个数组,数组中存放着每一个Promise的结果,并且是对应一个对象的;这个对象中包含status状态,以及对应的value值

3.  race

race是竞技、赛跑的意思,也就是谁先有结果我就要谁,这个result拿到的结果就不是一个数组了,而是最快的一个Promise resolve出来的结果

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    resolve(obj)
  }, 2000)
})

const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})

Promise.race([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

看下控制台的打印:

因为p3用时最短,最快,所以result拿到的就是p3resolve出的结果值,但是如果最快的那个reject了呢我们看一下:

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    reject('出错了~~~')
  }, 500)
})

const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})

Promise.race([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

我们修改一下代码,将p2时间设置为0.5s,且是rejected的状态,我们再看下打印结果:

直接就会被catch捕获了,这样看来,如果最快的那个状态为rejected状态的话,那我们后面的resolve的状态也拿不到值了。如果我们想拿到最快的fulfilled状态的值,也就是如果前面有reject的,我们就忽略掉,接着等待下一个resolve的,怎么做呢,这就有了any方法

4. any

const p1 = new Promise((resolve, reject) => {
  const obj = { data: '11111' }
  setTimeout(() => {
    resolve(obj)
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  const obj = { data: '22222' }
  setTimeout(() => {
    reject('出错了~~~')
  }, 500)
})

const p3 = new Promise((resolve, reject) => {
  const obj = { data: '33333' }
  setTimeout(() => {
    resolve(obj)
  }, 1000)
})

Promise.any([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err)
})

还是上一次的代码,我们把方法改为any,再看一下打印结果:

我们在1s后就会拿到p3 resolve的结果, 那个p2 reject的就忽略掉了,那如果我们所有的Promise都是rejected状态时它会怎么做呢?我们看一下:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('出错了111~~~')
  }, 3000)
})

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('出错了222~~~')
  }, 500)
})

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('出错了333~~~')
  }, 1000)
})

Promise.any([p1, p2, p3]).then(result => {
  console.log(result)
}).catch(err => {
  console.log('err:', err, err.errors)
})

我们看下打印结果:

它就会走catch了,并且打印出了错误信息,其中的 err.errors中会有我们reject传递的错误信息,err是它内部封装的错误提示

到此这篇关于详解JavaScript中Promise类的使用方法的文章就介绍到这了,更多相关JavaScript Promise类内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JS Promise axios 请求结果后面的.then() 是什么意思

    目录 Promise 对象 Promise 对象的状态 回调函数 Promise.then() 绑定回调函数 使用 Promise:链式调用 链式调用的实现 错误处理 常见错误 创建 Promise 对象 Promise 其他静态方法 创建已决议的 Promise 对象 多个 Promise 对象 结语&参考文献 Promise 是JS中一种处理异步操作的机制,在现在的前端代码中使用频率很高.Promise 这个词可能有点眼生,但你肯定见过 axios.get(...).then(res =>

  • JavaScript实现手写promise的示例代码

    目录 背景 需求 then的链式调用 Promise.all 背景 promise 作为前端开发中常用的函数,解决了 js 处理异步时回调地狱的问题,大家应该也不陌生了,今天来学习一下 promise 的实现过程,这样可以加(面)深(试)理(要)解(考). 需求 我们先来总结一下 promise 的特性: 使用: const p1 = new Promise((resolve, reject) => { console.log('1'); resolve('成功了'); }) console.l

  • 一文总结JavaScript中Promise遇到的问题

    目录 什么是Promise 1. 是否可以使用return 代替 resolve 2. 使用throw还是reject? 示例1:不会被catch的throw Error 示例2:不使用reject而使用throw 3. Promise的执行时间 3.1 resolve后面的代码会不会被执行? 3.2 当Promise遇到setTimeout 3.3 async/await 与Promise 什么是Promise 国内比较流行的看法: 阮一峰: Promise 对象 Promise 是异步编程的

  • JavaScript使用Promise实现并发请求数限制

    目录 没有Promise的并发请求 使用Promise限制并发请求 使用Promise实现并发请求数限制 总结 没有Promise的并发请求 在Web开发中,我们经常需要发起多个异步请求来获取数据.例如,我们可能需要从服务器获取一些用户信息.文章内容.评论列表等等.如果我们使用的是传统的JavaScript回调函数,可能会写出类似下面这样的代码: function getUsers(callback) { fetch('https://example.com/users', (response)

  • JavaScript promise的使用和原理分析

    目录 一.为什么一个promise可以调用多个.then方法 二.什么是Promise.resolve() 三.Promise.all缺陷和Promise.allSettled 四.Promise.race() 使用 一.为什么一个promise可以调用多个.then方法 如下面的: const promise = new Promise((resolve, reject) => { resolve("hahaha") }) // 1.同一个Promise可以被多次调用then方

  • 详解Java中Period类的使用方法

    目录 简介 Duration和Period 创建方法 通过时间单位创建 通过LocalDate创建 解析方法 比较方法 增减方法 转换单位 取值方法 简介 本文用示例介绍java的Period的用法. Duration和Period 说明 Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒.时间量可以为正也可以为负,比如1天(86400秒0纳秒).-1天(-86400秒0纳秒).1年(31556952秒0纳秒).1毫秒(0秒1000000纳秒)等. Period类通过年.月.日

  • 详解Java中Duration类的使用方法

    目录 简介 Duration和Period 创建方法 通过时间单位创建 通过LocalDateTime或LocalTime 通过已有的Duration 解析方法 用法说明 详解 比较方法 增减方法 转换单位 取值方法 简介 本文用示例介绍java的Duration的用法. Duration和Period 说明 Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒.时间量可以为正也可以为负,比如1天(86400秒0纳秒).-1天(-86400秒0纳秒).1年(31556952秒0纳

  • 详解Java中Optional类的使用方法

    目录 一.Optional类的来源 二.Optional类是什么 三.Optional类用法 四.代码示例 1.创建Optional类 2.判断Optional容器中是否包含对象 3.获取Optional容器的对象 4.过滤 5.映射 五.什么场景用Optional 1.场景一 2.场景二 3.场景三 4.场景四 一.Optional类的来源 到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因.以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optiona

  • 举例详解JavaScript中Promise的使用

    摘录 – Parse JavaScript SDK现在提供了支持大多数异步方法的兼容jquery的Promises模式,那么这意味着什么呢,读完下文你就了解了. "Promises" 代表着在javascript程序里下一个伟大的范式,但是理解他们为什么如此伟大不是件简单的事.它的核心就是一个promise代表一个任务结果,这个任务有可能完成有可能没完成.Promise模式唯一需要的一个接口是调用then方法,它可以用来注册当promise完成或者失败时调用的回调函数,这在Common

  • 详解JavaScript中的链式调用

    链模式 链模式是一种链式调用的方式,准确来说不属于通常定义的设计模式范畴,但链式调用是一种非常有用的代码构建技巧. 描述 链式调用在JavaScript语言中很常见,如jQuery.Promise等,都是使用的链式调用,当我们在调用同一对象多次其属性或方法的时候,我们需要多次书写对象进行.或()操作,链式调用是一种简化此过程的一种编码方式,使代码简洁.易读. 链式调用通常有以下几种实现方式,但是本质上相似,都是通过返回对象供之后进行调用. this的作用域链,jQuery的实现方式,通常链式调用

  • 详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不是基于'类的',而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能

  • 详解Javascript 中的 class、构造函数、工厂函数

    到了ES6时代,我们创建对象的手段又增加了,在不同的场景下我们可以选择不同的方法来建立.现在就主要有三种方法来构建对象,class关键字,构造函数,工厂函数.他们都是创建对象的手段,但是却又有不同的地方,平时开发时,也需要针对这不同来选择. 首先我们来看一下,这三种方法是怎样的 // class 关键字,ES6新特性 class ClassCar { drive () { console.log('Vroom!'); } } const car1 = new ClassCar(); consol

  • 详解javascript中的Strict模式

    简介 在ES5中,引入了strict模式,我们可以称之为严格模式.相应的sloppy mode就可以被称为非严格模式. 严格模式并不是非严格模式的一个子集,相反的严格模式在语义上和非严格模式都发生了一定的变化,所以我们在使用过程中,一定要经过严格的测试.以保证在严格模式下程序的执行和非严格模式下的执行效果一致. 使用Strict mode strict mode会改变javascript的一些表现,我们将会在下一节中进行详细的讲解. 这里先来看一下,怎么使用strict mode. Strict

  • 详解JavaScript中Arguments对象用途

    目录 前言 Arguments 的基本概念 Arguments 的作用 获取实参和形参的个数 修改实参值 改变实参的个数 检测参数合法性 函数的参数个数不确定时,用于访问调用函数的实参值 遍历或访问实参的值 总结 在实际开发中,Arguments 对象非常有用.灵活使用 Arguments 对象,可以提升使用函数的灵活性,增强函数在抽象编程中的适应能力和纠错能力. JavaScript 中 Arguments 对象的用途总结. 前言 相信我们很多人在代码开发的过程中都使用到过一个特殊的对象 --

  • 详解JavaScript 中的批处理和缓存

    场景 最近在生产环境遇到了下面这样一个场景: 后台在字典表中存储了一些之前需要前后端共同维护的枚举值,并提供根据 type/id 获取字典的 API.所以在渲染列表的时候,有很多列表的字段直接就是字典的 id,而没有经过后台的数据拼装. 起初,吾辈解决问题的流程如下 确定字典字段,添加转换后的对象类型接口 将对象列表进行转换得到其中字典字段的所有值 对字典 id 列表进行去重 根据 id 列表从后台获取到所有的字典数据 将获得的字典数据转换为 id => 字典 的 Map 遍历最初的列表,对里面

随机推荐