Skip to content

一个缓存异步函数返回值的方法 #29

@hstarorg

Description

@hstarorg

V1 版本:

import { EventEmitter } from "events"; const bus = new EventEmitter(); // 缓存队列 const cacheMap: Map< string, { status: "pending" | "loading" | "succeed" | "failed"; data?: any; queue: string[]; } > = new Map(); async function asyncCache(cacheKey: string, asyncFn: () => Promise<any>) { // 先初始化缓存 if (!cacheMap.has(cacheKey)) { cacheMap.set(cacheKey, { status: "pending", queue: [] }); } const fnId = Math.random().toString(16).slice(2); // 缓存对象,可直接修改对象属性 let cacheItem = cacheMap.get(cacheKey); // 有缓存成功的数据,直接返回 if (cacheItem.status === "succeed") { return cacheItem.data!; } // 加入队列 cacheItem.queue.unshift(fnId); // 有请求中的数据,先加入队列 if (cacheItem.status === "loading") { await new Promise((resolve) => { bus.on("ASYNC_DONE", () => { // 如果数据缓存成功或者队列中轮到自己,就停止等待 if ( cacheItem.status === "succeed" || fnId === cacheItem.queue[cacheItem.queue.length - 1] ) { resolve(1); } }); }); } cacheItem = cacheMap.get(cacheKey); // 有缓存成功的数据,直接返回 if (cacheItem.status === "succeed") { return cacheItem.data!; } cacheItem.status = "loading"; return Promise.resolve() .then(() => { return asyncFn(); }) .then((data) => { // 记录缓存状态和缓存数据 cacheItem.status = "succeed"; cacheItem.data = data; return data; }) .catch((reason) => { cacheItem.status = "failed"; return Promise.reject(reason); }) .finally(() => { // 结束了自己出队 cacheItem.queue.pop(); // 通知其他等待的请求 bus.emit("ASYNC_DONE"); }); } 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions