轻松理解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 ...
随机推荐
- 大文件分片上传,后端拼接保存(前端:antd;后端:.Net 5 WebAPI)
前言 对于普通业务场景而言,直接用 FormData() 将文件以入参的一个参数传给后端即可,但此方法有一个弊端就是,有个 30M 的上限. 对于动辄几百 M.几个 G 的文件上传需求,FormDat ...
- C#--String.Substring方法
第一种:String.SubString(int start,int length) 截取指定长度的字符串 这里有两个int型的参数 string表示字符串截取的起始位置,length表截取的 ...
- Cookie、Session、Token与JWT(跨域认证)
之前看到群里有人问JWT相关的内容,只记得是token的一种,去补习了一下,和很久之前发的认证方式总结的笔记放在一起发出来吧. Cookie.Session.Token与JWT(跨域认证) 什么是Co ...
- Go语言正/反向代理的姿势
先重温一下什么叫反向代理,正向代理. 鹅厂二面,nginx回忆录 所谓正向,反向代理取决于代理的是出站请求,还是入站请求. 正向代理: 代理的出站请求, 客户端能感知到代理程序,架构上距离客户端更近. ...
- GAMES101课程 作业6 源代码概览
GAMES101课程 作业6 源代码概览 Written by PiscesAlpaca(双鱼座羊驼) 一.概述 本篇将从main函数为出发点,按照各cpp文件中函数的调用顺序和层级嵌套关系,简单分析 ...
- Go语言核心36讲52
你好,我是郝林. 专栏到这里,就要结束了. 差不多在半年以前(2018年的第二个季度),极客时间的总编辑郭蕾找到我,说想让我写一个关于Go语言的技术专栏. 我那时候还在轻松筹担任大数据负责人,管理着四 ...
- HDC.Cloud Day | 全国首场上海站告捷,聚开发者力量造梦、探梦、筑梦
摘要:11月20日,首个华为云开发者日HDC.Cloud Day在上海成功举行. 本文分享自华为云社区<HDC.Cloud Day | 全国首场上海站告捷,聚开发者力量造梦.探梦.筑梦>, ...
- redisson分布式锁原理剖析
redisson分布式锁原理剖析 相信使用过redis的,或者正在做分布式开发的童鞋都知道redisson组件,它的功能很多,但我们使用最频繁的应该还是它的分布式锁功能,少量的代码,却实现了加锁. ...
- matplotlib详细教学
Matplotlib初相识 认识matplotlib Matplotlib是一个Python 2D绘图库,能够以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形,用来绘制各种静态,动态,交互式的 ...
- svn 日常使用的错误集锦
1.SVN:Previous operation has not finished; run 'cleanup' if it was interrupted 当时遇到这个问题时,找了各种解决方案什么要 ...