图片预加载使用Promise限制加载并发数量

719 阅读1分钟

图片预加载限制并发数量

如果想要限制接口请求数量只需要替换loadImage方法即可

主要使用了队列来进行限制并发,一开始截取并发limit大小的值进行入队,在promise.race后替换队列中的任务,然后一直使用递归进行并发限制

export function preloadImage(urls: string[], limit = 5) {
  const copyurls = [...urls];
  function loadImage(url: string) {
    return new Promise<string | HTMLImageElement>(resolve => {
      const image = lynx.createImage(url);
      image.addEventListener('load', () => {
        console.log(url, '加载成功');
        resolve(image);
      });
      image.addEventListener('error', () => {
        console.error(url, '加载失败');
        resolve(url);
      });
    });
  }
  /**
    * 生成一个队列,首先队列的长度是前limit个url,因此使用slice进行切片,然后使用map函数返回一个加载完后的promise
  	*/
  const taskQueue = copyurls.slice(0, limit).map((url, index) => loadImage(url).then(() => index));
  /**
    * 未加载url删除该长度
  	*/
  copyurls.splice(0, limit);
  /**
    * 使用递归进行入队操作
  	*/
  function enqueue(index: number): Promise<void> {
  /**
    * 如果未加载url列表为空就表示全部加载完成
  	*/
    if (copyurls.length === 0) {
      return Promise.resolve();
    }
    /**
    * 任务队列将已经加载完成的任务替换为当前的加载任务
  	*/
    taskQueue.splice(
      index,
      1,
      loadImage(copyurls.shift()!).then(() => index)
    );
    /**
    * 使用race方法,有任何一个加载完成时进行递归
  	*/
    return Promise.race(taskQueue).then(currentIndex => enqueue(currentIndex));
  }
  /**
    * 在最后将没有加载完的任务队列使用all方法进行加载
  	*/
  return Promise.race(taskQueue)
    .then(enqueue)
    .then(() => Promise.all(taskQueue));
}

const urls = [
  'https://www.kkkk1000.com/images/getImgData/getImgDatadata.jpg',
  'https://www.kkkk1000.com/images/getImgData/gray.gif',
  'https://www.kkkk1000.com/images/getImgData/Particle.gif',
  'https://www.kkkk1000.com/images/getImgData/arithmetic.png',
  'https://www.kkkk1000.com/images/getImgData/arithmetic2.gif',
  'https://www.kkkk1000.com/images/getImgData/getImgDataError.jpg',
  'https://www.kkkk1000.com/images/getImgData/arithmetic.gif',
  'https://www.kkkk1000.com/images/wxQrCode2.png',
];
preloadImage(urls).then(() => {
  console.error('全部加载成功');
});