Skip to main content

请求处理相关

请求去重

请实现一个 cacheRequest 方法,保证发出多次同一个 ajax 请求时都能拿到数据,而实际上只发出一次请求

const request = (url, option) =>
new Promise((resolve) => {
setTimeout(() => {
resolve({ data: option });
}, 2000);
});
const cache = new Map();

const cacheRequest = (url, option) => {
const key = `${url}:${option.method}`;
if (cache.has(key)) {
if (cache.get(key).status === "pending") {
return cache.get(key).myWait;
}
return Promise.resolve(cache.get(key).data);
}
// 无缓存,发起真实请求
const requestApi = request(url, option);
cache.set(key, { status: "pending", myWait: requestApi });

return requestApi
.then((res) => {
cache.set(key, { status: "success", data: res });
return res;
})
.catch((err) => {
cache.set(key, { status: "fail", data: err });
console.log(err);
})
.finally(() => {
cache.delete(key);
});
};

并行控制请求

  • async-pool
// 并行控制请求
function asyncPool(poolLimit, array, iteratorFn) {
let i = 0;
const ret = [];
// 正在执行
const executing = [];
const enqueue = () => {
// 边界处理,array为空数组
if (i === array.length) {
return Promise.resolve();
}
// 每调一次enqueue,初始化一个promise
const item = array[i++];
const p = Promise.resolve().then(() => iteratorFn(item, array));
// 放入promises数组
ret.push(p);
// promise执行完毕,从executing数组中删除
const e = p.then(() => executing.splice(executing.indexOf(e), 1));
executing.push(e);
// 使用Promise.rece,每当executing数组中promise数量低于poolLimit,就实例化新的promise并执行
let r = Promise.resolve();
if (executing.length >= poolLimit) {
r = Promise.race(executing);
}
// 递归,直到遍历完array
return r.then(() => enqueue());
};
return enqueue().then(() => Promise.all(ret));
}

promise 池

// promise 池
const promisePool = async function (functions, n) {
// 使用 Set 存储正在执行的任务队列
const queue = new Set();
const resolved = [];

// eslint-disable-next-line no-restricted-syntax
for (const task of functions) {
// 将正在执行的任务加入到队列中
// eslint-disable-next-line promise/always-return
const x = task().then((res) => {
// 任务执行完成后将结果存到 resolved 数组中
resolved.push(res);
// 完成后移出正在执行队列
queue.delete(x);
});
queue.add(x);
// 控制线程池执行最大数
if (queue.size >= n) {
// eslint-disable-next-line no-await-in-loop
await Promise.race(queue);
}
}
// 执行完所有任务后才返回执行结果
await Promise.allSettled(queue);
return resolved;
};

如何确保返回数据的顺序?并非响应的顺序

串行控制

  • await+for.of

处理大数据

渲染百万条结构简单的大数据