“多线程”Promise 工具类
方案一 推荐
// 最大并发限制数
const 最大并发限制数 = 5;
// 创建一个计数器,用于限制并发请求数量
var 当前并行数量 = 0;
// 请求列表
const 请求列表 = [];
// 成功回调函数
const callback = (request) => {
console.log('当前并行数量:' + 当前并行数量 + " 请求结束:", request);
};
for (let i = 0; i < 15; i++) {
请求列表.push('请求' + i)
}
// 成功回调函数
const 开始 = async () => {
// 发送请求
await sendRequest(请求列表, 最大并发限制数, callback);
console.log('全部执行完毕')
console.log('执行最后一个请求完成')
};
//开始
开始()
/**
* 并行发送请求
* @param 请求列表
* @param limits 并行上限
* @param callback 回调
* @returns {Promise<void>}
*/
async function sendRequest(请求列表, 最大并发限制数, callback) {
//单个的请求方法
const 执行请求 = async (request) => {
// 执行请求的逻辑,这里使用console.log语句作为示例
console.log('当前并行数量:' + 当前并行数量 + " 请求开始,入参:", request);
try {
// 模拟请求的异步执行
let res = await new Promise((resolve) => setTimeout(()=>{resolve(request+"-返回值:成功")}, 3000));
// 请求完成后调用回调函数
callback({入参:request, 状态:true, 返回值:res});
}catch (e) {
// 出错
callback({入参:request, 状态:false, 异常:e});
}
};
// 创建一个计数器,用于限制并发请求数量
当前并行数量 = 0;
// const controlConcurrency = async () => {
// while (当前并行数量 < 最大并发限制数 && 请求列表.length > 0) {
// const 请求 = 请求列表.shift(); // 取出下一个请求
// 当前并行数量++;
// await 执行请求(请求); // 执行请求
// 当前并行数量--;
// }
//
// // 检查是否还有未完成的请求
// if (当前并行数量 === 0 && 请求列表.length === 0) {
// callback(); // 所有请求完成后调用回调函数
// }
// };
// 启动并发控制
// for (let i = 0; i < 最大并发限制数; i++) {
// controlConcurrency();
// }
let promiseArr = []
// 启动并发控制
for (let i = 0; i < 最大并发限制数; i++) {
// 并发控制函数
const promise = new Promise(async (resolve) => {
while (当前并行数量 < 最大并发限制数 && 请求列表.length > 0) {
const 请求 = 请求列表.shift(); // 取出下一个请求
当前并行数量++;
await 执行请求(请求); // 执行请求
当前并行数量--;
}
// 检查是否还有未完成的请求
if (当前并行数量 === 0 && 请求列表.length === 0) {
callback(); // 所有请求完成后调用回调函数
}
//当前结束
resolve()
});
promiseArr.push(promise)
}
//等待全部结束
await Promise.all(promiseArr)
console.log('启动并发控制执行完毕')
}
//方案二
vue
that = this
或者用 全局变量
map = {count:0}
//阻塞并获取额度 await WTool.Thread.sleepLimit(that, '变量名称', 500)
await WTool.Thread.sleepLimit(map, 'count', 500)
Thread:{
/**
* 阻塞x毫秒
* 使用方法
* await sleep(5000) 等待5秒
* @param time
* @returns {Promise<void>}
*/
async sleep(time){
await new Promise(resolve => setTimeout(resolve, time))
},
/**
* 阻塞获取额度
* 使用方法
* await sleepLimit(that, 字段, 1000)
* @param _vm that
* @param field 字段
* @param time 多久判断一次
* @returns {Promise<boolean>}
*/
async sleepLimit(_vm, field, time){
if(time){
time = 500
}
let flag = true
while(flag){
if(_vm[field] > 0){
// if(_vm[field].length > 0){
//睡眠等待
await WTool.Thread.sleep(time);
//有额度了
flag = false
_vm[field]--
// _vm[field].shift()
console.log('有额度了,获取名额之后:',_vm[field])
return true
}else{
//睡眠等待
await WTool.Thread.sleep(time);
}
}
},
/**
* 等待额度释放完毕
* 使用方法
* await join(that, 字段, 1000)
* @param _vm that
* @param field 字段
* @param time 多久判断一次
* @returns {Promise<boolean>}
*/
async join(_vm, field, realCount, time){
if(time){
time = 2000
}
let flag = true
while(flag){
if(_vm[field] >= realCount){
// if(_vm[field].length >= realCount){
console.log('所有额度释放完毕:',_vm[field])
//有额度了
flag = false
return true
}else{
//睡眠等待
await WTool.Thread.sleep(time);
}
}
}
},
核心就是阻塞 等待其他完成
其他方案
参考
浅谈JS阻塞方式怎么实现异步任务队列?-云搜网 (27ka.cn)
let queue = []
let index = 0
function clickMe() {
queue.push({
name: 'click',
index: index++
})
}
run()
async function run() {
while (true) {
if (queue.length > 0) {
let obj = queue.shift()
let res = await request(obj.index)
console.log('已处理事件' + res)
} else {
await wait(500)
console.log('----- 队列空闲中 -----')
}
}
}
// 通过setTimeout模拟异步请求
function request(index) {
return new Promise(function (resolve, reject) {
setTimeout(() => {
resolve(index)
}, 1000)
})
}
function wait(time) {
return new Promise(function (resolve) {
setTimeout(() => {
resolve()
}, time)
})
}
其他方案
// 异步请求队列
const queue = []
// 用来模拟不同的返回值 let index = 0
// 标志是否正在处理队列中的请求
let running = false
// 使用setTimeout模拟异步请求
function request(index) {
return new Promise(function (resolve) {
setTimeout(() => {
resolve(index)
}, 1000)
})
}
// 连续点击,触发异步请求,加入任务队列
function clickMe() {
addQueue(() => request(index++))
}
// 当队列中任务数大于0时,开始处理队列中的任务
function addQueue(item) {
queue.push(item)
if (queue.length > 0 && !running) {
running = true
process()
}
}
function process() {
const item = queue.shift()
if (item) {
item().then(res => {
console.log('已处理事件' + res)
process()
})
} else {
running = false
}
}