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
  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/qc-one/p/14893764.html
Copyright © 2011-2022 走看看