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));
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM