使用泛型为异步队列提供任务类型

Posted

技术标签:

【中文标题】使用泛型为异步队列提供任务类型【英文标题】:Provide Task type for async queue using generics 【发布时间】:2018-12-04 13:09:50 【问题描述】:

我现在有这个:

export type EVCb = (err:any, val?:any) => void;
export type Task = (cb: EVCb) => void;
export const q = async.queue((task: Task, cb) => task(cb), 2);

有没有办法使用泛型提供有关任务的 async.queue 类型信息?

类似这样的:

export const q = async.queue<Task>((task: Task, cb) => task(cb), 2);

我不知道这是否是正确的方法或正确的语法是什么。

【问题讨论】:

@types/async 是否存在于 async.js?如果存在,可以安装npm install @types/async 是的,当然@types/async 存在,但鉴于此,如果可能的话,我正在寻找如何为此获得正确的通用参数。 看到您标记为已回答,如果答案有用,请不要忘记分配赏金 :) 知道了,非常感谢 【参考方案1】:

async 的类型定义需要 2-3 个类型参数。在有 2 个参数的版本中,第一个参数是任务类型,第二个参数是回调。我的猜测是,这些类型定义是在条件类型可用于从任务中提取回调类型之前编写的(或者维护者不希望使用条件类型来保持与低于 2.8 的版本的兼容性)。

可以传入第二个参数:

export const q2 = async.queue<Task, EVCb>((task, cb) => task(cb), 2);

编辑

我们还可以添加一个新的 async 方法作为模块扩充,它只需要一个参数,因为从 typescript 2.8 开始,现在可以从其他类型中提取类型参数(如果任何人都愿意这样做):

declare module 'async' 
    type GetCallbackParameter<T extends (cb: any)=> void> = T extends (cb: infer C)=> void ? C: never;

    export function queue<T extends (cb: any)=> void>(worker: async.AsyncWorker<T,GetCallbackParameter<T>> , concurrency?: number): AsyncQueue<T>;


export const q2 = async.queue<Task>((task, cb) => task(cb), 2); // cb inferred correctly

【讨论】:

以上是关于使用泛型为异步队列提供任务类型的主要内容,如果未能解决你的问题,请参考以下文章

基于多线程任务队列执行时间测试——泛型单例模式落地

JavaScript 异步栈事件循环任务队列

一篇搞定(Js异步事件循环与消息队列微任务与宏任务)

一篇搞定(Js异步事件循环与消息队列微任务与宏任务)

异步任务类AnsycTask的三个参数

Flask+Celery+Redis实现队列化异步任务