当前位置:网站首页>【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);
}),
];
总结
边栏推荐
猜你喜欢
Flink HA配置
基于STM32F407的一个温度传感器报警系统(用的是DS18B20温度传感器,4针0.96寸OLED显示屏,并且附带日期显示)
服务网格istio 1.12.x安装
Tensorflow踩坑笔记,记录各种报错和解决方法
Mesos learning
OSPF网络类型
AWS 常用服务
【论文阅读-表情捕捉】High-quality Real Time Facial Capture Based on Single Camera
IDEA 配置连接数据库报错 Server returns invalid timezone. Need to set ‘serverTimezone‘ property.
IT系统运行维护方法及策略
随机推荐
ECCV2022 | RU & Google propose zero-shot object detection with CLIP!
【数据库和SQL学习笔记】9.(T-SQL语言)定义变量、高级查询、流程控制(条件、循环等)
读论文-Cycle GAN
dataframe 常用操作
Flink Broadcast 广播变量
Detailed explanation of BroadCast Receiver (broadcast)
AWS 常用服务
Flink EventTime和Watermarks案例分析
Comparison and summary of Tensorflow2 and Pytorch in terms of basic operations of tensor Tensor
如何编写一个优雅的Shell脚本(三)
Mesos learning
PoE视频监控解决方案
【Pytorch学习笔记】8.训练类别不均衡数据时,如何使用WeightedRandomSampler(权重采样器)
网络信息安全运营方法论 (中)
【Pytorch学习笔记】9.分类器的分类结果如何评估——使用混淆矩阵、F1-score、ROC曲线、PR曲线等(以Softmax二分类为例)
关于基于若依框架的路由跳转
OSPF故障排除办法
MySQL
WCH系列芯片CoreMark跑分
沁恒MCU从EVT中提取文件建立MounRiver独立工程