应用场景:在指定函数产生结果之前,防止重复运行指定的函数,比如,接口重复请求。
/***
* 在指定函数产生结果之前,防止重复运行指定的函数
*/
function usePrmoiseResult() {
const map = new Map()
/**
* 指定函数产生结果之前,防止重复运行指定函数
* @param fn 指定函数,可以是一个async异步函数
* @param key 防止重复运行的唯一值
* @returns
*/
const awaitPrmoiseResult = async function <T>(fn: () => T, key: any): Promise<T> {
if (!map.has(key)) {
map.set(key, Promise.all([fn()]))
}
return map.get(key).then((result: any[]) => {
return result[0]
}).finally(() => {
map.delete(key)
})
}
const removePrmoiseResult = function (key: any) {
map.delete(key)
}
const clearPrmoiseResult = function () {
Array.from(map.keys()).forEach((key: any) => {
map.delete(key)
});
}
return {
awaitPrmoiseResult,
removePrmoiseResult,
clearPrmoiseResult
}
}
使用案例1(异步函数):
const { awaitPrmoiseResult } = usePrmoiseResult()
window.onclick = () => {
const fn = async () => {
console.log("运行指定函数", new Date().toLocaleTimeString())
await awaitTime(5000)
return 123
}
awaitPrmoiseResult(fn, "asdsds").then((res: any) => {
console.log("产生结果了", res, new Date().toLocaleTimeString())
})
}
连续点击6次,打印结果如下:
虽然连续点击了6次,但指定函数只执行一次,并且函数执行的结果共享,作为了其他相同key的指定函数的结果。
- 是不是 像 相同接口重复请求,多个相同请求共享一份数据的场景呢!!!他可以使用在请求当中去。
- 是不是可以做为立即运行的防抖函数呢!!!防止重复点击。
使用案例2(普通函数):
const { awaitPrmoiseResult } = usePrmoiseResult()
window.onclick = () => {
const fn = () => {
console.log("运行指定函数", new Date().toLocaleTimeString())
return 123
}
awaitPrmoiseResult(fn, "asdsds").then((res: any) => {
console.log("产生结果了", res, new Date().toLocaleTimeString())
})
}
连续点击6次,打印结果如下: