举个例子,现在有巨量的图片需要展示,要求实现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个,不符合题目一个接一个并发执行的要求。