异步场景题
1. 限制异步操作的并发个数并尽可能快的完成全部
有8个图片资源的url,已经存储在数组urls中。
urls类似于['https://image1.png', 'https://image2.png', ....]
而且已经有一个函数function loadImg,输入一个url链接,返回一个Promise,该Promise在图片下载完成的时候resolve,下载失败则reject。
但有一个要求,任何时刻同时下载的链接数量不可以超过3个。
请写一段代码实现这个需求,要求尽可能快速地将所有图片下载完成。
js
function loadLimit(urls, fetch, limit = 3) {
return new Promise((resolve) => {
const results = [];
let index = 0; // 当前正在处理的 url 索引
let active = 0; // 当前正在执行的任务数量
function next() {
if (index >= urls.length && active === 0) {
resolve(results); // 全部处理完成
return;
}
while(active < limit && index < urls.length) {
const currIndex = index;
const url = urls[index++];
active++;
fetch(url).then((res) => {
results[currIndex] = { status: 'fulfilled', value: res }
}).catch( err => {
results[currIndex] = { status: 'rejected', reason: err }
}).finally(() => {
active--;
next();
})
}
}
next();
});
}2. 在纯函数编码中如果消除异步的传染性?
这里的main必须是一个纯函数,不能包含任何副作用,在消除异步中,会调用两个次的
js
async function getUserData() {
console.log("Fetching user data...");
return Promise.resolve({ name: "John Doe" });
}
function main() {
console.log('Start main function');
const userData = runAsync(getUserData, main);
console.log(userData);
}
main();
function runAsync(asyncTask, contextFn) {
if (asyncTask.cache) {
const cache = asyncTask.cache;
delete cache.cache;
return cache;
}
asyncTask.cache = null;
Promise.resolve(asyncTask()).then((res) => {
asyncTask.cache = res;
}).catch((err) => {
asyncTask.cache = err;
}).finally(() => {
contextFn();
})
}