zoukankan      html  css  js  c++  java
  • js实现并发控制

    一、使用promise实现并发控制

    在前端优化性能的时候, 我们可以考虑使用并发控制
    比如首页有10个并发请求, 先发送3个, 3个中哪一个响应了, 立即发送第4个, 直到第10个发送完成

    function limitLoad(urls, handler, limit) {
        const sequence = [].concat(urls)
        let promise = []
        promise = sequence.splice(0, limit).map((url, index) => {
            return handler(url).then(()=>{
                return index
            })
        })
        let p = Promise.race(promise)
        // for循环给p赋值相当于.then().then()链式调用
        for (let i= 0; i< sequence.length; i++) {
            p = p.then(res => {
                promise[res] = handler(sequence[i]).then(()=>{
                    return res
                })
                return Promise.race(promise)
            })
        }
    }
    
    const urls =[
        {info:'1', time:2000},
        {info:'2', time:1000},
        {info:'3', time:2000},
        {info:'4', time:2000},
        {info:'5', time:3000},
        {info:'6', time:1000},
        {info:'7', time:2000},
        {info:'8', time:2000},
        {info:'9', time:3000},
        {info:'10', time:1000}
    ]
    
    function loadImg(url){
        return new Promise((reslove, reject)=>{
            console.log(url.info + '---start')
            setTimeout(()=>{
                console.log(url.info, 'ok!!!')
                reslove()
            }, url.time)
        })
    }
    
    limitLoad(urls, loadImg, 3)
    function asyncPool(poolLimit, array, iteratorFn) {
      let i = 0;
      const ret = []; // 存储所有的异步任务
      const executing = []; // 存储正在执行的异步任务
      const enqueue = function () {
        if (i === array.length) {
          return Promise.resolve();
        }
        const item = array[i++]; // 获取新的任务项
        const p = Promise.resolve().then(() => iteratorFn(item, array));
        ret.push(p);
     
        let r = Promise.resolve();
     
        // 当poolLimit值小于或等于总任务个数时,进行并发控制
        if (poolLimit <= array.length) {
          // 当任务完成后,从正在执行的任务数组中移除已完成的任务
          const e = p.then(() => executing.splice(executing.indexOf(e), 1));
          executing.push(e);
          if (executing.length >= poolLimit) {
            r = Promise.race(executing); 
          }
        }
     
        // 正在执行任务列表 中较快的任务执行完成之后,才会从array数组中获取新的待办任务
        return r.then(() => enqueue());
      };
      return enqueue().then(() => Promise.all(ret));
    }
    Talk is cheap,show me the code
  • 相关阅读:
    HDU 2112 HDU Today
    HDU 1869 六度分离
    HDU 3790 最短路径问题
    HDU2066 一个人的旅行
    HDU1596 find the safest road(最短路)
    HDU 1254 推箱子(双重bfs)
    HDU 1429 胜利大逃亡(续) (bfs+状态压缩)
    HDU 1045 Fire Net
    数据结构之单链表头插法,尾插法
    Java--会移动、反弹的球
  • 原文地址:https://www.cnblogs.com/qc-one/p/14893764.html
Copyright © 2011-2022 走看看