Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Provide Task type for async queue using generics

I have this right now:

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);

Isn't there a way to give async.queue type information about the task using generics?

something like this:

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

I can't figure out if this is the right way to do it or what the right syntax is.

like image 959
Alexander Mills Avatar asked Jun 25 '18 21:06

Alexander Mills


People also ask

What is the syntax of async queue?

Syntax of async.queue. The parameter function is executed on the element added to the queue. The concurrency value tells the queue, the number of elements to be processed at a particular time. Example: Have a look at the below example for better understanding.

What is generic queue and how to use it?

At the end of this article, you will understand what exactly Generic Queue is and when and how to use Generic Queue in C# with examples. What is Generic Queue in C#? The Generic Queue is a collection class which works on the principle of First In First Out (FIFO) and this class is present in System.Collections.Generic namespace.

What is system threading extend async?

Extend async to support task types that match a specific pattern, in addition to the well known types System.Threading.Tasks.Task and System.Threading.Tasks.Task<T>. A task type is a class or struct with an associated builder type identified with System.Runtime.CompilerServices.AsyncMethodBuilderAttribute .

What is the use of task queue?

Task queue (or) Job queue plays an important role in a web application where it schedules programs (or) jobs to the queue for batch processing. This enables services (or) programs to execute in the background without disturbing other processes. This Task Queue is designed for asynchronous work.


1 Answers

The type definitions for async require 2-3 type arguments. In the version with 2 arguments, the first argument is the task type, and the second argument is the callback. My guess is that these type definitions were written before conditional type were available to extract the callback type from the task (or that the maintainers don't wish to use conditional types to maintain compatibility with versions lower then 2.8).

You can pass in the second parameter:

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

Edit

We can also add a new async method as a module augmentation, that only requires one parameter, as since typescript 2.8 it is now possible to extract type parameters from other types (this could be a good contribution to the definitions if anyone is willing to do it):

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
like image 79
Titian Cernicova-Dragomir Avatar answered Sep 19 '22 14:09

Titian Cernicova-Dragomir