【前端】js 多个并行的Promise阻塞工具 指定同时执行数量

"多线程"Promise 工具类

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)

javascript 复制代码
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)
    })
}

其他方案

javascript 复制代码
// 异步请求队列 
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
    }
}
相关推荐
中微子2 分钟前
React状态管理最佳实践
前端
烛阴11 分钟前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
中微子18 分钟前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...27 分钟前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
nananaij28 分钟前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
初遇你时动了情28 分钟前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
dssxyz32 分钟前
uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
javascript·微信小程序·uni-app
阿蒙Amon38 分钟前
为什么 12 版仍封神?《C# 高级编程》:从.NET 5 到实战架构,进阶者绕不开的必修课
开发语言·c#
无小道40 分钟前
c++-引用(包括完美转发,移动构造,万能引用)
c语言·开发语言·汇编·c++
爱莉希雅&&&1 小时前
技术面试题,HR面试题
开发语言·学习·面试