如何替代自定义PromiseChain实现文件读写任务串行化?
替代自定义PromiseChain的简便实现方案
你的自定义PromiseChain已经很好地解决了串行执行异步任务、避免文件冲突的问题,但确实有更简便的原生实现或工具类方案可选:
一、原生Promise简化实现(无需自定义类)
不需要封装完整类,仅用一个变量维护当前Promise链即可,逻辑和你的实现完全一致,但更轻量化:
let currentPromise = Promise.resolve(); const pushToChain = <T, TResult1 = T, TResult2 = never>( onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null ): Promise<TResult1 | TResult2> => { currentPromise = currentPromise.then(onfulfilled).catch(onrejected); return currentPromise; };
使用方式和原代码完全兼容:
const defer = (message: string, timeout: number) => () => new Promise((resolve) => setTimeout(() => resolve(message), timeout)).then(console.log); pushToChain(defer('1st', 1000), (error) => console.log(error.message)); pushToChain(defer('2nd', 500));
二、批量任务用Array.reduce串行执行
如果你的任务是预先确定的列表,直接用Array.prototype.reduce即可构建串行链,省去手动push的步骤:
const tasks = [ defer('1st', 1000), defer('2nd', 500) ]; // 串行执行所有任务,错误捕获后不中断后续流程 tasks.reduce((chain, task) => { return chain.then(task).catch(err => { console.log(err.message); return Promise.resolve(); // 返回resolved保证链条继续执行 }); }, Promise.resolve());
三、RxJS实现动态串行任务
如果考虑使用RxJS,Subject搭配concatMap可以完美实现动态添加任务并串行执行的需求,同时自带成熟的错误处理机制:
import { Subject, of, from } from 'rxjs'; import { concatMap, catchError } from 'rxjs/operators'; // 创建任务流Subject,用于动态推送任务 const taskQueue = new Subject<() => Promise<string>>(); // 订阅任务流,concatMap强制任务串行执行 taskQueue.pipe( concatMap(task => { return from(task()).pipe( catchError(err => { console.log(err.message); return of(null); // 错误后返回空值,确保流不中断 }) ); }) ).subscribe(); // 动态添加任务 taskQueue.next(defer('1st', 1000)); taskQueue.next(defer('2nd', 500));
这种方式适合复杂的异步任务调度场景,RxJS还能提供更多操作符扩展功能(比如任务取消、限流等)。
内容的提问来源于stack exchange,提问作者striderhobbit
相关产品推荐
相关产品推荐

