关于js,promise并发问题

async function test1 (data, index, limit) {
    let len = data.length
    let result = []
    while (index < len) {
      let res = await fnFunction()
      result = result.concat(res)
      index += limit
    }
    return result
  }

await等待太久,页面卡顿,浏览器卡死

  async function asyncPool (poolLimit, array, iteratorFn) {
    const ret = [] // 用于存放所有的promise实例
    const executing = [] // 用于存放目前正在执行的promise
    for (const item of array) {
      const p = Promise.resolve(iteratorFn(item)) // 防止回调函数返回的不是promise,使用Promise.resolve进行包裹
      ret.push(p)
      if (poolLimit <= array.length) {
        // then回调中,当这个promise状态变为fulfilled后,将其从正在执行的promise列表executing中删除
        const e = p.then(() => executing.splice(executing.indexOf(e), 1))
        executing.push(e)
        if (executing.length >= poolLimit) {
          // 一旦正在执行的promise列表数量等于限制数,就使用Promise.race等待某一个promise状态发生变更,
          // 状态变更后,就会执行上面then的回调,将该promise从executing中删除,
          // 然后再进入到下一次for循环,生成新的promise进行补充
          await Promise.race(executing)
        }
      }
    }
    return Promise.all(ret)
  }

Promise.all太多会卡死

 

  /**
   * arrs 请求数据源数组
   * limit 是每次并行发起多少个请求
   * handleFn 就是异步处理函数
  */
  async function limitQueueFn (arrs, limit, handleFn) {
    // 完成任务数
    let runningIndex = 0 // 这是正在执行的下标
    let finishedIndex = 0 // 这是已经执行完的下表
    let result = new Array(arrs.length).fill(0) // 建立一个空数组, 存储结果
    return new Promise((resolveFn, rejectFn) => {
      // 第一次的时候 一次性执行 limit 个任务
      for (let i = 0; i < limit; i++) {
        run()
      }
      // 执行一个任务
      function run () {
        // 构造待执行任务 当该任务完成后 如果还有待完成的任务 继续执行任务
        new Promise((resolve, reject) => {
          const value = arrs[runningIndex]
          runningIndex++ // 这个是同步操作
          resolve(handleFn(value))
        }).then((res) => {
          result[finishedIndex] = res
          finishedIndex++
          if (runningIndex < arrs.length) {
            run()
          } else { // 全部执行完毕
            resolveFn(result)
          }
        })
      }
    })
  };

栈太深,卡死

  async function finallyFn (data, max) {
    let pool = []
    for (let i = 0; i < queueList.length; i++) {
      let promise = Fn()
      promise.then((res) => {
        console.log(`id${res}的请求已经处理完毕,当前并发为${pool.length}`)
        pool.splice(pool.indexOf(promise), 1)
      })
      pool.push(promise)
      //这里是重点,当满了就阻塞
      if (pool.length == max) {
        await Promise.race(pool)
      }
    }
    return data.length
  }

防止promise.all过多卡死,去除promise.all,采用setinterval等待结果,结束进程,对于项目可用

posted @ 2023-03-15 12:58  张天才科技  阅读(146)  评论(0编辑  收藏  举报