如何确保fp-ts中executeImport执行完成后再运行其他任务?
问题分析与解决方案
你的问题核心在于:handleImages()、handleEvents()、handlePage()在getDatas函数被调用时就已经立即执行了,和executeImport的执行顺序完全无关。
原因是你用TE.right(handleImages())时,handleImages()会被立即求值,返回的Promise直接被包装成了TaskEither。哪怕你用了TE.ApplicativeSeq,它只能控制TaskEither的执行顺序,但这些Promise已经提前启动了,自然会和executeImport并行运行。
正确写法:确保executeImport完成后再执行后续任务
要实现executeImport执行完毕后再触发后续任务,需要把这些任务包装成依赖executeImport结果的TaskEither,用TE.chain来串联执行流程:
import { pipe } from 'fp-ts/function'; import * as TE from 'fp-ts/TaskEither'; import { sequenceS } from 'fp-ts/Apply'; export const getDatas = (config) : TE.TaskEither<Error | Errors, { res: { pool: ConnectionPool; operators: IOperatorDB[]; orders: IMachineOrderItem[]; documents: IMachineDocument[]; stages: IProdStage[]; aImgs: IAImg[]; bImgs: IBImg[]; calendarEvents: ICalendarEvent[]; page: IPage[]; }; handleImages: void; handleCalendarEvent: void; handlePage: void; }> => pipe( // 第一步:先执行executeImport,等待它完成 executeImport(config), // 第二步:拿到executeImport的结果后,再执行后续任务 TE.chain(res => // 这里可以选择并行(ApplicativePar)或顺序(ApplicativeSeq)执行三个handle任务 sequenceS(TE.ApplicativePar)({ res: TE.right(res), // 用TE.tryCatch包裹Promise,捕获可能的错误 handleImages: TE.tryCatch( () => handleImages(), err => err as Error ), handleCalendarEvent: TE.tryCatch( () => handleEvents(), err => err as Error ), handlePage: TE.tryCatch( () => handlePage(), err => err as Error ), }) ) );
关键细节说明
TE.chain的作用:只有当前一个TaskEither(executeImport)成功完成时,才会执行chain里的逻辑,确保后续任务在executeImport之后启动。TE.tryCatch的必要性:如果handleImages()等可能抛出错误,用tryCatch可以把Promise转换成TaskEither,统一错误处理逻辑(如果你的handle函数不会出错,也可以用TE.fromPromise)。- 并行/顺序选择:
- 用
TE.ApplicativePar:三个handle任务在executeImport完成后并行执行,效率更高。 - 用
TE.ApplicativeSeq:三个handle任务按顺序依次执行,前一个完成后再启动下一个。
- 用
- 传递
res参数:如果后续handle任务需要用到executeImport返回的res数据,直接在chain的回调里传入即可,比如() => handleImages(res)。
内容的提问来源于stack exchange,提问作者betta7391
相关产品推荐
相关产品推荐

