import { AsArray } from '../../interface'; import { isAsync, isFunc, isPromise } from '../../utils'; import { IHookCallItem } from '../interface/i-hook-call-item'; import { SyncSeriesHook } from '../sync-series-hook/sync-series-hook'; /** * 串联钩子,按照注册顺序执行 * * @export * @class AsyncSeriesHook * @template T 输入值类型 * @template C 上下文声明对象 */ export class AsyncSeriesHook extends SyncSeriesHook { /** * 触发钩子,当某个钩子返回「null」时,中断后续执行。 * * @param {C} context * @param {...AsArray} args * @return {*} {Promise} * @memberof AsyncSeriesHook */ async call(context: C, ...args: AsArray): Promise { const _context: C = context || Object.create({}); let obj: any; for (let i = 0; i < this.items.length; i++) { const item = this.items[i]; if (item.fn) { if (item.mode === 'promise') { obj = item.fn(_context, ...args); if (isPromise(obj)) { // eslint-disable-next-line no-await-in-loop obj = await obj; } } else { obj = item.fn(_context, ...args); } } if (obj === null) { console.warn( `因${ item.fn ? item.fn.name : null }方法返回值为「null」,钩子中断执行。`, item, ); break; } } return _context; } /** * 注册异步钩子 * * @param {((...args: AsArray) => Promise)} fn 回调 * @memberof AsyncSeriesHook */ tapPromise(fn: (context: C, ...args: AsArray) => Promise): void { if (fn && (isFunc(fn) || isAsync(fn))) { const opt: IHookCallItem = { mode: 'promise', }; opt.fn = fn as any; this.items.push(opt); } } /** * 删除异步钩子注册 * * @author chitanda * @date 2021-04-30 14:04:42 * @param {(context: C, ...args: AsArray) => Promise} callBack */ removeTapPromise( callBack: (context: C, ...args: AsArray) => Promise, ): void { this.removeTap(callBack); } }