Skip to content

Latest commit

 

History

History
72 lines (65 loc) · 1.72 KB

多异步任务保持3个并发.md

File metadata and controls

72 lines (65 loc) · 1.72 KB

多异步任务保持3个并发

举个例子,现在有巨量的图片需要展示,要求实现promise的并发控制,例如要求同时进行3个图片的加载,始终加载3个

function limitLoad(urls, handler, limit) {
  const sequence = [].concat(urls);
  let promises = [];

  promises = sequence.splice(0, limit).map((url, index) => {
    return handler(url).then(() => {
      // 当执行完之后,再填补一个,所有需要知道哪个执行完了
      return index;
    });
  });

  // 通过竞速选出第一个执行完的
  // 补充,出现执行完的之后,其他的还会执行,只是race函数只返回了最快的。
  let p = Promise.race(promises);
  for (let i = 0; i < sequence.length; i++) {
    // 最终p会变成 p.then().then().then()... 它是通过链式调用的形式去不断的竞速和填充
    p = p.then((res) => {
      promises[res] = handler(sequence[i]).then(() => {
        return res;
      });
      return Promise.race(promises);
    });
  }
}
// 模拟url地址和加载时间
const mockUrls = [
  {
    url: "地址1",
    time: 2000,
  },
  {
    url: "地址2",
    time: 2300,
  },
  {
    url: "地址3",
    time: 4000,
  },
  {
    url: "地址4",
    time: 3000,
  },
  {
    url: "地址5",
    time: 2000,
  },
  {
    url: "地址6",
    time: 1000,
  },
];

// 设置要执行的任务
function loadImg(url) {
  return new Promise((resolve, reject) => {
    console.log("-----" + url.url + "start!");
    setTimeout(() => {
      console.log(url.url + "---OK!!!");
      resolve();
    }, url.time);
  });
}

limitLoad(mockUrls, loadImg, 3);

如果用for循环+promise.all的会执行完3个再去执行3个,不符合题目一个接一个并发执行的要求。