javascript异步之Promise.all()、Promise.race()、Promise.finally()

7次阅读

共计 3405 个字符,预计需要花费 9 分钟才能阅读完成。

同期异步系列文章推荐谈一谈 javascript 异步 javascript 异步中的回调 javascript 异步与 promisejavascript 异步之 Promise.resolve()、Promise.reject()javascript 异步之 Promise then 和 catchjavascript 异步之 async(一)javascript 异步之 async(二)javascript 异步实战 javascript 异步总结归档
今天我们继续讨论 promise 网络上关于 PromiseAPI 使用的文章多如牛毛,为了保持 javascript 异步系列文章的完整性,现在对 promise 的 API 进行简单全面的介绍
准备工作
我在 easy-mock 添加了三个接口,备用依然使用 axios 进行 ajax 请求
Promise.all()
Promise.all() 有点像“并行”我们看一个栗子
<!DOCTYPE html>
<html lang=”en”>

<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<title>promise</title>
<script src=”https://unpkg.com/axios/dist/axios.min.js”></script>
</head>

<body>
<script>
{
const p1 = axios.get(‘https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1’)
.then(({
data
}) => {
console.log(‘p1 成功啦 ’);
return data.data
})

const p2 = axios.get(‘https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise2’)
.then(({
data
}) => {
console.log(‘p2 成功啦 ’);
return data.data
})

const p3 = axios.get(‘https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock’)
.then(({
data
}) => {
console.log(‘p3 成功啦 ’);
return data.data
})

const p = Promise.all([p3, p1, p2])
.then(arr => {
console.log(arr);
console.log(‘Promise.all 成功啦 ’);
})
.catch(err=>{
console.log(err,’Promise.all 错啦 ’);
})
}
</script>
</body>

</html>
我们知道 axios 返回的是一个 promise 对象, 我们可以看下
console.log(p1);
Promise.all 就是用于将多个 Promise 实例,包装成一个新的 Promise 实例 Promise.all, 接收一个数组作为参数,数组的每一项都返回 Promise 实例我们重点看这段代码
const p = Promise.all([p3, p1, p2])
.then(arr => {
console.log(arr);
console.log(‘Promise.all 成功啦 ’);
})
.catch(err=>{
console.log(err,’Promise.all 错啦 ’);
})
p1,p2,p3 都是返回 promise 实例,Promise.all 不关心他们的执行顺序, 如果他们都返回成功的状态,Promise.all 则返回成功的状态,输出一个数组,是这三个 p1,p2,p3 的返回值,数组的顺序和他们的执行顺序无关,和他们作为参数排列的顺序有关我们看下输出为了是拉长接口三的返回时间我对接口三的数据进行了修改,返回值是长度 1000-2000 之间的随机数组,所以 p3 的执行要晚于 p1 和 p2,但我们输出的 arr,p3 依然在前面,这给我们带来一个便利,返回值数组的顺序和方法的执行顺序无关,可以进行人为进行控制我们将 p1 做一下改动,使 p1 报错
const p1 = axios.get(‘https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/promise1’)
.then(({
data
}) => {
console.log(‘p1 成功啦 ’);
return xxxx.data// 将 data.data 修改为 xxxx.data
})
如果有一个返回失败(reject),Promise.all 则返回失败(reject)的状态,此时第一个被 reject 的实例的返回值,会传递给 P 的回调函数。三个 promise 实例参数之间是“与”的关系,全部成功,Promise.all 就返回成功,有一个失败,Promise.all 就返回失败换个角度说,一个 promise 的执行结果依赖于另外几个 promise 的执行结果,例如:几个 ajax 全部执行完了,才能渲染页面,几个 ajax 全部执行完了,才能做一些数据的计算操作,不关心执行顺序,只关心集体的执行结果
Promise.race()
Promise 中的竞态,用法和 Promise.all 类似,对应参数的要求和 Promise.all 相同,传入一个数组作为参数,参数要返回一个 Promise 实例 race 就是竞争的意思,数组内的 Promise 实例,谁执行的快,就返回谁的执行结果,不管是成功还是失败
const p = Promise.race([p3, p1, p2])
.then(res => {
console.log(res);
console.log(‘Promise.all 成功啦 ’);
})
.catch(err=>{
console.log(err,’Promise.all 错啦 ’);
})
通过输出我们发现 p1 是第一个完成的,所以 p 的返回结果就是 p1 的执行结果而且就算完成,但是 进程不会立即停止,还会继续执行下去。
关于 race 的使用场景
搜了一下,很多文章都说是用来解决网络超时的提示,类似于下面这样
const p3 = axios.get(‘https://easy-mock.com/mock/5b0525349ae34e7a89352191/example/mock’)
.then(({
data
}) => {
console.log(‘p3 成功啦 ’);
return data.data
})
const p4 = new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error(‘ 网络连接超时 ’)), 50)
})
const p = Promise.race([p3, p4])
.then(res => console.log(res))
.catch(err => console.log(err));
p3 的 ajax 和 50ms 的定时器比较,看谁执行的快,如果超过了 50ms,p3 的 ajax 还没返回,就告知用户网络连接超时这里有个问题,就算提示超时了,p3 还在继续执行,它并没有停下来,直到有状态返回个人观点:race 可以用来为 ajax 请求的时长划定范围,如果 ajax 请求时长超过 xxxms 会执行某个方法,或者 ajax 请求时长不超过 xxms 会执行某个方法,总之,race 的应用空间不是很大
Promise.finally()
finally 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
const p = Promise.race([p3, p4])
.then(res => console.log(res))
.catch(err => console.log(err))
.finally(() => {
console.log(“finally 的执行与状态无关 ”)
});
当 promise 得到状态(不论成功或失败)后就会执行 finally,
原文链接
参考链接 Promise 对象 Promise.prototype.finally

正文完
 0