轻松理解Promise.all 、Promise.then、Promise.race有什么区别以及使用方法
简单来说呢,Promse.all一般应用于某个场景需要多个接口数据合并起来才能实现
有个极大地好处我必须说一下,请求顺序和获取数据顺序是一样的哟,大可放心使用~~
const success1 = new Promise((res,rej) => {
const data = {status: 'success', message:'success1'}
res(data)
})
const error1 = new Promise((res,rej) => {
const data = {status: 'error', message:'error1'}
rej(data.message)
})
const success2 = new Promise((res,rej) => {
const data = {status: 'success', message:'success2'}
res(data)
})
const error2 = new Promise((res,rej) => {
const data = {status: 'error', message:'error2'}
rej(data)
})
Promise.all([success1, success2]).then(res => {
console.log('Promise.all([success1, success2]).then')
console.log(res)
}).catch(error => {
console.log('Promise.all([success1, success2]).catch')
console.log(error)
})
// 打印结果
// Promise.all([success1, success2]).then
// 0: {status: "success", message: "success1"}
// 1: {status: "success", message: "success2"}
// length: 2
// __proto__: Array(0)
Promise.all([success1, error1, success2]).then(res => {
console.log('Promise.all([success1, error1, success2]).then')
console.log(res)
}).catch(error => {
console.log('Promise.all([success1, error1, success2]).catch')
console.log(error)
})
// 打印结果
// Promise.all([success1, error1, success2]).catch
// error1
Promise.all([success1, error1, success2, error2]).then(res => {
console.log('Promise.all([success1, error1, success2, error2]).then')
console.log(res)
}).catch(error => {
console.log('Promise.all([success1, error1, success2, error2]).catch')
console.log(error)
})
// 打印结果
// Promise.all([success1, error1, success2, error2]).catch
// error1
总结:按照上面的使用方法
所有结果成功>按顺序返回成功
有一个失败>返回第一个失败的那个
重点来了~~ 解决有一个失败就全盘失败的方法如下
Promise.all(
[
success1.catch(err=>err),
error1.catch(err=>err),
success2.catch(err=>err),
error2.catch(err=>err)
]
)
.then((res) => {
console.log(res)
if (res[0] && res[0].status == 'success') {
console.log('res[0]success', res[0])
} else {
console.log('res[0]error', res[0])
}
if (res[1] && res[1].status == 'success') {
console.log('res[1]success', res[1])
} else {
console.log('res[1]error', res[1])
}
if (res[2] && res[2].status == 'success') {
console.log('res[2]success', res[2])
} else {
console.log('res[2]error', res[2])
}
if (res[3] && res[3].status == 'success') {
console.log('res[3]success', res[3])
} else {
console.log('res[3]error', res[3])
}
})
// 打印结果
// res[0]success {status: "success", message: "success1"}
// res[1]error error1
// res[2]success {status: "success", message: "success2"}
// res[3]error {status: "error", message: "error2"}
来说一下Promise.prototype.then
下个请求依赖上个请求获取的数据
function P1() {
return new Promise((res, rej) => {
const data = { status: 'success', message: 'res2依赖的数据' }
setTimeout(() => {
res(data)
}, 1000)
})
}
function P2(params) {
return new Promise((res, rej) => {
const data = { status: 'success', message: 'res3依赖的数据', r: params }
setTimeout(() => {
res(data)
}, 2000)
})
}
function P3(params) {
return new Promise((res, rej) => {
const data = { status: 'success', message: '最终结果', r: params }
setTimeout(() => {
res(data)
}, 3000)
})
}
try {
P1()
.then((res) => P2(res))
.then((res) => P3(res))
.then((res) => {
console.log(JSON.stringify(res))
})
} catch (e) {
console.log('执行请求出错', e)
}
// 打印结果
// {
// status: 'success',
// message: '最终结果',
// r: {
// status: 'success',
// message: 'res3依赖的数据',
// r: { status: 'success', message: 'res2依赖的数据' },
// },
// }
最后来看一下Promise.race,简单来说就是几个请求比赛跑步,看谁跑得快,跑的最快的就会被直接返回,不论成功还是失败.
let suc1 = new Promise((res, rej) => {
setTimeout(() => {
res('success1000')
}, 1000)
})
let suc2 = new Promise((res, rej) => {
setTimeout(() => {
res('success1500')
}, 1500)
})
let err1 = new Promise((res, rej) => {
setTimeout(() => {
rej('failed500')
}, 500)
})
let err2 = new Promise((res, rej) => {
setTimeout(() => {
rej('failed500')
}, 2000)
})
Promise.race([suc1, err1])
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
// 打印结果
// failed500
Promise.race([suc1, suc2, err2])
.then((result) => {
console.log(result)
})
.catch((error) => {
console.log(error)
})
// 打印结果
// success1000
附promise.race源码,
重点:Constructor.resolve(entries[i]).then(resolve, reject);
通过循环promise 最终的resolve接收为同一个
function race(entries) {
/*jshint validthis:true */
var Constructor = this; // this 是调用 race 的 Promise 构造器函数。
if (!isArray(entries)) {
return new Constructor(function (_, reject) {
return reject(new TypeError('You must pass an array to race.'));
});
} else {
return new Constructor(function (resolve, reject) {
var length = entries.length;
for (var i = 0; i < length; i++) {
Constructor.resolve(entries[i]).then(resolve, reject);
}
});
}
}
总结:由此可以看到,我们可以用它来
1.测试接口的响应速度
2.当用户信号不好的时候可以发出网络不好的提示信息
3.后端代码部署了很多服务器,我们可以看哪个速度快就用哪个的数据
欢迎路过的小伙伴们继续补充哦~~
结语
欢迎大家指出文章需要改正之处~
如果有更好的方法,欢迎大家提出来,共同进步哟~~
轻松理解Promise.all 、Promise.then、Promise.race有什么区别以及使用方法的更多相关文章
- 深入理解JS异步编程三(promise)
jQuery 原本写一个小动画我们可能是这样的 $('.animateEle').animate({ opacity:'.5' }, 4000,function(){ $('.animateEle2' ...
- 【JavaScript进阶】深入理解JavaScript中ES6的Promise的作用并实现一个自己的Promise
1.Promise的基本使用 // 需求分析: 封装一个方法用于读取文件路径,返回文件内容 const fs = require('fs'); const path = require('path') ...
- 手写一款符合Promise/A+规范的Promise
手写一款符合Promise/A+规范的Promise 长篇预警!有点长,可以选择性观看.如果对Promise源码不是很清楚,还是推荐从头看,相信你认真从头看到尾,并且去实际操作了,肯定会有收获的.主要 ...
- 一步一步实现一个Promise A+规范的 Promise
2015年6月,ES2015(即ES6)正式发布后受到了非常多的关注.其中很重要的一点是 Promise 被列为了正式规范. 在此之前很多库都对异步编程/回调地狱实现了类 Promise 的应对方案, ...
- promise核心6 自定义promise
1.定义整体结构(不写实现) 定义一个自己的promise的库 lib(库的简写) 一个js文件.一个js模块(不能用es6 也不能commjs)(用es5模块语法 ) 匿名函数自调用.IIFE ( ...
- promise核心 为什么用promise
为什么要用promise 1.使用纯回调函数 先指定回调函数,再启动异步任务 答 1.指定回调函数的方式更加灵活 可以在执行任务前,中,后 2.支持链式调用,解决回调地狱问题 什么是回调地狱:回调函数 ...
- 到底什么是promise?有什么用promise怎么用
相信很多人刚接触promise都会晕,但学会后却离不开它,本文详细介绍一下promise,promise解决的问题,帮助新手快速上手 [扫盲] 什么是promise? promise是一种约定,并非一 ...
- Promise.resolve( data)与Promise.reject( data )
Promise.resolve( data)与Promise.reject( data ) 常用来生成已经决议失败或成功的promise实例: 1.Promise.reject(data)不管传递的是 ...
- 轻松理解Redux原理及工作流程
轻松理解Redux原理及工作流程 Redux由Dan Abramov在2015年创建的科技术语.是受2014年Facebook的Flux架构以及函数式编程语言Elm启发.很快,Redux因其简单易学体 ...
- 轻松理解MYSQL MVCC 实现机制
轻松理解MYSQL MVCC 实现机制 转载https://blog.csdn.net/whoamiyang/article/details/51901888 1. MVCC简介 1.1 什么是MVC ...
随机推荐
- 1.-Django项目结构
一.Django简介 Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,视图V和模版T. Django基本组件: 1.基本配置文件/路由系统 2. ...
- .NET中的拦截器filter的使用
拦截器的使用 使用场景分析 我们先想像一个场景,就是程序员开发软件,他是怎么工作的呢?我们都知道,普通的程序员只需要根据需求文档开发相应的功能即可,他不用和客户谈论软件需求,不用理会软件卖多少钱,他要 ...
- 微信小程序经纬度转化为具体位置(逆地址解析)
小程序wx.getLocation只能获取经纬度, 这时候想要具体地址就需要借助第三方sdk(逆地址解析) 我这边第三方以腾讯位置服务举例 一. 首先小程序需要申请wx.getLocation接口权限 ...
- 2022-11-09 Acwing每日一题
本系列所有题目均为Acwing课的内容,发表博客既是为了学习总结,加深自己的印象,同时也是为了以后回过头来看时,不会感叹虚度光阴罢了,因此如果出现错误,欢迎大家能够指出错误,我会认真改正的.同时也希望 ...
- 2022春每日一题:Day 28
题目:最大上升子序列和 就是最长上升子序列的改版,贡献由1改为a[i]其他全部不变 代码: #include <cstdio> #include <cstdlib> #incl ...
- 【ASP.NET Core】MVC控制器的各种自定义:修改参数的名称
在上一篇中,老周演示了通过实现约定接口的方式自定义控制器的名称. 至于说自定义操作方法的名称,就很简单了,因为有内置的特性类可以用.看看下面的例子. [Route("[controller] ...
- 图文详解在VMware Workstation 16 PRO虚拟机上安装Ubuntu 22.04.5 linux系统
一.下载Ubuntu linux系统镜像 机构 下载地址 官网地址 https://cn.ubuntu.com/download 南京大学 https://mirrors.nju.edu.cn/ubu ...
- apktool回编译报错
报错 error: No resource identifier found for attribute 'XXX' in package 'XXX' 解决 将xml文件中 "http:// ...
- 关于sublime-build的配置详解
前言 sublime-build 可以做很多自定义的构建命令,然后用其执行代码,十分方便! 开始 这里我就简单的用python 的配置来详细说明各个配置项目的作用 { "shell_cmd& ...
- 上传文件到阿里云 oss,前端 browser.js 笔记
Web端常见的上传方法是用户在浏览器或App端上传文件到应用服务器,应用服务器再把文件上传到OSS. 和数据直传到OSS相比,有以下缺点 上传慢:用户数据需先上传到应用服务器,之后再上传到OSS 费用 ...