图片预加载限制并发数量
如果想要限制接口请求数量只需要替换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('全部加载成功');
});