在一次异步调用完成之前,所有后续调用进行等待,直到函数完成,共享调用结果。
注意:该设计模式,由于多次调用共享一次调用结果,对函数有幂等和入参固定的要求。
- 安装
npm i @jerryc/concurrent-merger
- 使用
import { ConcurrentMerger } from '@jerryc/concurrent-merger';
// 一个请求远程资源的异步函数
const getAssets = async () => API.requestAssets();
// 创建 ConcurrentMerger 实例
const concurrentMerger = new ConcurrentMerger({ name: 'test-merger' });
// 代理原函数
const getAssetsProxy = concurrentMerger.proxy(getAssets);
// 高频并发调用 getAssetsProxy,在第一次请求回调之前,后续请求会入队进行等待,直到请求完之后,释放队列,共享结果。
getAssetsProxy().then(result => ...);
getAssetsProxy().then(result => ...);
getAssetsProxy().then(result => ...);
getAssetsProxy().then(result => ...);
// 输出 log
// [concurrent-merger:info] test-merger-任务队列-入列(1/100, id: db3116bd-e4e7-4c6e-9397-32ce015e6225)
// [concurrent-merger:info] test-merger-任务队列-执行目标方法
// [concurrent-merger:info] test-merger-任务队列-入列(2/100, id: a0b206ba-a3af-4e54-9f99-13206595d1df)
// [concurrent-merger:info] test-merger-任务队列-入列(3/100, id: 2dc2f30b-66ff-4101-9eff-56530131689c)
// [concurrent-merger:info] test-merger-任务队列-入列(4/100, id: 580fa99c-8794-495c-b805-8c72978e3fa1)
// [concurrent-merger:info] test-merger-任务队列-消费-resolve(id: 2dc2f30b-66ff-4101-9eff-56530131689c)
// [concurrent-merger:info] test-merger-任务队列-消费-resolve(id: 580fa99c-8794-495c-b805-8c72978e3fa1)
// [concurrent-merger:info] test-merger-任务队列-消费-resolve(id: fa597867-38ef-4e84-ae21-6760a136ab15)
// [concurrent-merger:info] test-merger-任务队列-消费-resolve(id: a9b1f027-c6ba-4895-a5a1-41be45853ba9)
如果你的项目中支持 TS
或者 ES Decorator
,那么 ConcurrentMerger
提供了快捷使用的装饰器。
import { decorator as concurrentMerger } from '@jerryc/concurrent-merger';
@concurrentMerger({ name: 'test-merger' })
async function getAsset() {
return API.requestAssets();
};
ConcurrentMerger
内置了一个迷你 logger(power by @jerryc/mini-logger),方便内部日志打印,外部可以获得 Logger
的实例,进行 log level 的控制。
import {
logger,
LoggerLevel,
ConcurrentMerger,
} from '@jerryc/concurrent-merger';
// 创建 ConcurrentMerger 实例
const concurrentMerger = new ConcurrentMerger({ name: 'test-merger' });
// 下调 Log level
logger.level = LoggerLevel.ERROR;
关于 Log Level 的详细,查看:@jerryc/mini-logger
详见:https://jerryc8080.github.io/concurrent-merger/
详见:https://jerryc8080.github.io/concurrent-merger/coverage/index.html