update: Promise.all 和 Promise.race举例

This commit is contained in:
qianguyihao 2021-05-25 23:39:32 +08:00
parent 8268cf5150
commit 110b928e67

View File

@ -202,21 +202,51 @@ Promise.all([promise1, promise2, promise3])
可以看到 promise2 执行失败之后马上就走到了 catch而且 promise3 里的 resolve 并没有执行 可以看到 promise2 执行失败之后马上就走到了 catch而且 promise3 里的 resolve 并没有执行
### Promise.all()举例图片上传 ### Promise.all()举例多张图片上传
比如说现在有一个**图片上传**的接口每次请求接口时只能上传一张图片需求是当用户连续上传完三张图片甚至是更多图片之后给用户一个上传成功的提示这个时候我们就可以使用`Promsie.all()` 比如说现在有一个**图片上传**的接口每次请求接口时只能上传一张图片需求是当用户连续上传完九张图片正好凑齐九宫格之后给用户一个上传成功的提示这个时候我们就可以使用`Promsie.all()`
代码举例如下
```js
const imgArr = ['1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg', '6.jpg', '7.jpg', '8.jpg', '9.jpg'];
const promiseArr = [];
imgArr.forEach((item) => {
const p = new Promise((resolve, reject) => {
// 在这里做图片上传的异步任务。图片上传成功后,接口会返回图片的 url 地址
// upload img ==> return imgUrl
if (imgUrl) {
// 单张图片上传完成
resolve(imgUrl);
} else {
reject('单张图片上传失败');
}
});
promiseArr.push(p);
});
Promise.all(promiseArr).then((res) => {
console.log('图片全部上传完成');
console.log('九张图片的url地址组成的数组' + res);
});
```
上面这个例子在实际的项目开发中经常遇到属于高频需求需要记住并理解
当然实战开发中在做多张图片上传时可能是一张一张地单独上传各自的上传进度相互独立此时 `Promise.all`便不再适用这就得具体需求具体分析了
## Promise.race() ## Promise.race()
`Promise.race([p1, p2, p3])`并发处理多个异步任务返回的是第一个执行完成的 promise且状态和第一个完成的任务状态保持一致参数里传的是多个 promise 实例组成的数组 `Promise.race([p1, p2, p3])`并发处理多个异步任务返回的是第一个执行完成的 promise且状态和第一个完成的任务状态保持一致参数里传的是多个 promise 实例组成的数组
上面这句话第一次读时可能很绕口我说的再通俗一点在多个同时执行的异步任务中先找出哪个异步任务**最先执行完成**无论是走到 resolve还是走到 reject都算执行完成然后整体的状态跟这个任务保持一致如果这个任务执行成功那整体就算成功走到 then如果这个任务执行失败那整体就算失败走到 catch 上面这句话第一次读时可能很绕口我说的再通俗一点在多个同时执行的异步任务中先找出哪个异步任务**最先执行完成**无论是走到 resolve还是走到 reject都算执行完成整体的状态跟这个任务保持一致如果这个任务执行成功那整体就算成功走到 then如果这个任务执行失败那整体就算失败走到 catch
`race`的中文翻译可以理解为竞赛意思是谁先抢到名额就认定谁了无论这个人最终的结局是成功或者失败整体的结局都以这个人的结局为准 `race`的中文翻译可以理解为竞赛意思是谁先抢到名额就认定谁了无论这个人最终的结局是成功或者失败整体的结局都以这个人的结局为准
我刚开始学 Promise.race()的时候误以为它的含义是只要有一个异步执行成功整体就算成功走到 then所有任务都执行失败整体才算失败走到 catch现在想来真是大错特错过于懵懂 我刚开始学 Promise.race()的时候误以为它的含义是只要有一个异步**执行成功**整体就算成功走到 then所有任务都执行失败整体才算失败走到 catch现在想来真是大错特错过于懵懂
我们来看看各种场景的打印结果便能让你擦干泪水继续前行 现在我顿悟了准确来说Promise.race()强调的是只要有一个异步任务**执行完成**整体就是**完成**
我们来看看各种场景的打印结果便能擦干泪水继续前行
### 语法举例 ### 语法举例
@ -376,6 +406,54 @@ Promise.race([promise1, promise2, promise3])
场景 3 的代码一定好好好理解 场景 3 的代码一定好好好理解
### Promise.race()举例
现在有个需求是这样的前端需要加载并显示一张图片如果图片在三秒内加载成功那就显示图片如果三秒内没有加载成功那就按异常处理前端提示加载超时
代码实现思路
```js
function getImg() {
return new Promise((resolve, reject) => {
let img = new Image();
img.onload = function () {
// 图片的加载,是异步任务
resolve(img);
};
img.src = 'https://img.smyhvae.com/20200102.png';
});
}
function timeout() {
return new Promise((resolve, reject) => {
// 采用 Promise.race()之后,如果 timeout() 的 promise 比 getImg() 的 promise先执行说明定时器时间到了那就算超时。整体的最终结果按失败处理。
setTimeout(() => {
reject('图片加载超时');
}, 3000);
});
}
Promise.race([getImg(), timeout()])
.then((res) => {
// 图片加载成功
console.log(res);
})
.catch((err) => {
// 图片加载超时
console.log(err);
});
```
如代码注释所述采用 Promise.race()之后如果 timeout() promise getImg() promise 先执行说明定时器时间到了那就算超时整体的最终结果按失败处理
这个思路很巧妙
## 总结
Promise 不仅能解决嵌套异步任务的**回调地域**问题也可做多个异步任务的**并发请求**还可以进行舒适简洁的状态管理
Promise 本身不是异步的但是它可以封装异步任务并对异步操作进行良好的状态管理这便是 Promise 的魅力所在
## 我的公众号 ## 我的公众号
想学习**更多技能**不妨关注我的微信公众号**千古壹号** 想学习**更多技能**不妨关注我的微信公众号**千古壹号**