当前位置:网站首页>【Promise高级用法】实现并行和串行API
【Promise高级用法】实现并行和串行API
2022-08-05 05:16:00 【六月的可乐】
Promise高级用法
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
串行API
提示:这里可以添加本文要记录的大概内容:
1、案例:实现一个promise队列----传入一个promise数组,一次串行执行并输出他们的成功或者失败结果
提示:以下是本篇文章正文内容,下面案例可供参考
一、思路总结
promise串行的实现基本思路是:
1、第一种是在前一个promise处于解决状态后执行下一个promise(也就是then方法中)
2、第二种则是通过递归调用的思路来依次执行promise
二、实现
1.代码实现
代码如下(示例):基于递归思想实现
function queuePromise(promiseArr) {
return new Promise((resolve, reject) => {
let arrLen = promiseArr.length;
let resArr = [];
if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
let ArrStatus = promiseArr.every(item => {
return item instanceof Promise;
});
if (!ArrStatus) return console.error('数组第每一项必须是promise');
try {
let num = 0;
function run(num) {
if (num >= arrLen) {
resolve(resArr);
return;
};
console.log('开始执行:'+num);
promiseArr[num].then((res) => {
resArr.push({
status: 1,
res,
});
console.log(res + '=>');
run(++num);
}, err => {
console.log(err + '-->');
resArr.push({
status: 0,
err,
});
run(++num);
});
};
run(num);
} catch (error) {
reject(error);
}
})
};
let arr = [new Promise(resolve => {
setTimeout(_ => {
resolve('3s');
}, 3000);
}), new Promise(resolve => {
setTimeout(_ => {
resolve('8s');
}, 3000);
}), new Promise((resolve, reject) => {
setTimeout(_ => {
resolve('18s');
// reject('18s');
}, 3000);
})];
// queuePromise(arr).then(res => {
// console.log('queuePromise=>', res);
// }).catch(err => {
// console.log('queuePromise-err=>', err);
// });
并行API
提示:这里可以添加本文要记录的大概内容:
1、案例:实现一个promise.All这样的并行API
提示:以下是本篇文章正文内容,下面案例可供参考
一、思路总结
promise并行的实现基本思路是:
1、第一种是for循环的实现方式,但是值得注意的是:
- 如果是异步写法for()、for of 和arr.forEach()实现是一致的都是互不干扰的并行模式
- 如果是async await的同步写法for()、for of实现将会是阻塞的串行方式,但是arr.forEach实现仍然是并行效果,因为forEach方法运行时候会独立开启自调用函数作用域
- 但是这两种实现并行都是没有固定开始执行顺序的
2、第二种通过arr.reduce取迭代执行,这只实现并行效果因为胃任务队列的原因会有先后执行的顺序
二、实现
1.代码实现
代码如下(示例):基于reduce思想实现
// 并行 但是由于微任务机制它们执行纯在先后顺序
let allPromise = (promiseArr) => {
let arrLen = promiseArr.length;
let resArr = [];
if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
let ArrStatus = promiseArr.every(item => {
return item instanceof Promise;
});
if (!ArrStatus) return console.error('数组第每一项必须是promise');
return new Promise((resolve, reject) => {
// console.log('quePromise+>', Array(...Array(arrLen).keys()));
Array(...Array(arrLen).keys()).reduce((promise, index) => {
console.log('------>', index, promise);
return promiseArr[index].then(res=> {
resArr.push({
status: 1,
res,
});
console.log(res + '=>');
(index == arrLen - 1) && resolve(resArr);
}, err => {
resArr.push({
status: 0,
err,
});
console.log(err + '-->');
(index == arrLen - 1) && resolve(resArr);
});
}, Promise.resolve('1'));
});
}
quePromise(arr).then(res => {
console.log('quePromise:', res);
})
代码如下(示例):基于forEach思想实现
// 实现promise.all----并行
let promiseAll = function(promiseArr) {
let arrLen = promiseArr.length;
let resoveCount = 0;
let resArr = new Array(arrLen);
if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
let ArrStatus = promiseArr.every(item => {
return item instanceof Promise;
});
if (!ArrStatus) return console.error('数组第每一项必须是promise');
return new Promise((resolve, reject) => {
promiseArr.forEach((promise, index) => {
promise.then(res => {
resArr[index] = res;
resoveCount ++;
if (resoveCount === arrLen) resolve(resArr);
}, err => {
reject(err);
});
});
}
代码如下(示例):基于forEach思想实现
// promise.race ---并行
function promiseRace(promiseArr) {
let arrLen = promiseArr.length;
let status = false;
if (!Array.isArray(promiseArr) || arrLen === 0) return console.error('必须传入非空数组!', Array.isArray(promiseArr) , arrLen);
let ArrStatus = promiseArr.every(item => {
return item instanceof Promise;
});
if (!ArrStatus) return console.error('数组第每一项必须是promise');
return new Promise((resolve, reject) => {
try {
promiseArr.forEach((item, index) => {
if (!status) {
item.then(res => {
resolve(res);
status = true;
}, error => {
reject(error);
})
};
});
} catch (error) {
reject(error);
}
})
};
let raceArr = [
new Promise((resolve, reject) => {
setTimeout(_ => {
resolve('race-----3s');
}, 3000);
}),
new Promise((resolve, reject) => {
setTimeout(_ => {
resolve('race-----2s');
}, 2000);
}),
new Promise((resolve, reject) => {
setTimeout(_ => {
resolve('race-----5s');
}, 5000);
}),
];
总结
边栏推荐
- 【论文精读】ROC和PR曲线的关系(The relationship between Precision-Recall and ROC curves)
- ECCV2022 | RU & Google propose zero-shot object detection with CLIP!
- OSPF网络类型
- [Pytorch study notes] 9. How to evaluate the classification results of the classifier - using confusion matrix, F1-score, ROC curve, PR curve, etc. (taking Softmax binary classification as an example)
- RecycleView和ViewPager2
- 原来何恺明提出的MAE还是一种数据增强
- 读论文- pix2pix
- spingboot 容器项目完成CICD部署
- 如何编写一个优雅的Shell脚本(三)
- Flink Table API 和 SQL之概述
猜你喜欢
Facial Motion Capture 调研
读论文-Cycle GAN
[Pytorch study notes] 11. Take a subset of the Dataset and shuffle the order of the Dataset (using Subset, random_split)
CAN、CAN FD
Comparison and summary of Tensorflow2 and Pytorch in terms of basic operations of tensor Tensor
【数据库和SQL学习笔记】7.SQL中的插入(INSERT)、删除(DELETE)、更新(UPDATE)
常见的 PoE 错误和解决方案
CVPR 2020 - 频谱正则化
基于STM32F407的WIFI通信(使用的是ESP8266模块)
CVPR 2022 |节省70%的显存,训练速度提高2倍
随机推荐
MySQL
MySql之索引
Comparison and summary of Tensorflow2 and Pytorch in terms of basic operations of tensor Tensor
哥廷根大学提出CLIPSeg,能同时作三个分割任务的模型
吞吐?带宽?傻傻分不清楚
如何编写一个优雅的Shell脚本(二)
MaskDistill-不需要标注数据的语义分割
Flink Table API 和 SQL之概述
如何编写一个优雅的Shell脚本(三)
el-pagination左右箭头替换成文字上一页和下一页
CVPR 2022 |节省70%的显存,训练速度提高2倍
Tensorflow踩坑笔记,记录各种报错和解决方法
如何编写一个优雅的Shell脚本(一)
CVPR best paper winner Huang Gao's team from Tsinghua University presented the first dynamic network review
2021电赛资源及经验总结
基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
The University of Göttingen proposed CLIPSeg, a model that can perform three segmentation tasks at the same time
Tensorflow2 与 Pytorch 在张量Tensor基础操作方面的对比整理汇总
el-pagination分页分页设置
【Over 15】A week of learning lstm