Skip to content

Correct way to obtain result using async functions in queue #2025

@niclasek

Description

@niclasek

Hello,
First of all, thank you for this great library!

This is not an issue but a question.

I'm using the queue functionality in async to commit database transactions. Below is an example of how I currently use it:

import { queue, QueueObject } from "async";

type QueueTask = { name: string };

export class AsyncLabWithoutAsyncFunction {
	private static _transactionQueue: QueueObject<QueueTask>;

	private static init(): void {
		AsyncLabWithoutAsyncFunction._transactionQueue = queue<QueueTask, string, Error>((task: QueueTask, callback): void => {
			try {
				const myNameInUpperCase: string = this.nameInUpperCase(task.name);
				callback(null, myNameInUpperCase);
			} catch (err) {
				callback(null, "error");
			}
		}, 1);
	}

	static async perform(nameInLowerCase: string): Promise<string> {
		if (AsyncLabWithoutAsyncFunction._transactionQueue == null) {
			AsyncLabWithoutAsyncFunction.init();
		}

		return new Promise<string>((resolve) => {
			try {
				AsyncLabWithoutAsyncFunction._transactionQueue.push({ name: nameInLowerCase }, (err, response: string) => {
					console.log(`response = ${response}`);
					console.log(`name = ${nameInLowerCase}`);
					resolve(response);
				});
			} catch (err) {
				resolve(null);
			}
		});
	}

	static nameInUpperCase(nameInLowerCase: string): string {
		return nameInLowerCase.toUpperCase();
	}
}

Now, I need to update my code to pass an async function to the queue, in which the callback isn't passed. From the documentation:

Using ES2017 async functions
Async accepts async functions wherever we accept a Node-style callback function. However, we do not pass them a callback, and instead use the return value and handle any promise rejections or errors thrown.

I struggled to find a way to retrieve the result of the database transaction, but I think I found a solution by adding .then(callback) when pushing to the queue:

import { queue, QueueObject } from "async";

type QueueTask = { name: string };

export class AsyncLabWithAsyncFunction {
	private static _transactionQueue: QueueObject<QueueTask>;

	private static init(): void {
		AsyncLabWithAsyncFunction._transactionQueue = queue(async (task: QueueTask): Promise<string> => {
			try {
				const myNameInUpperCase: string = await this.nameInUpperCase(task.name);
				return myNameInUpperCase;
			} catch (err) {
				return "error";
			}
		}, 1);
	}

	static async perform(nameInLowerCase: string): Promise<string> {
		if (AsyncLabWithAsyncFunction._transactionQueue == null) {
			AsyncLabWithAsyncFunction.init();
		}

		return new Promise<string>((resolve) => {
			try {
				AsyncLabWithAsyncFunction._transactionQueue.push({ name: nameInLowerCase }).then((response: string) => {
					console.log(`response = ${response}`);
					console.log(`name = ${nameInLowerCase}`);
					resolve(response);
				});
			} catch (err) {
				resolve(null);
			}
		});
	}

	static nameInUpperCase(nameInLowerCase: string): Promise<string> {
		return new Promise<string>((resolve) => {
			setTimeout(() => {
				resolve(nameInLowerCase.toUpperCase());
			}, 1_000);
		});
	}
}

Question:
Is this the correct way to obtain the result when using async functions in queue?

Thanks a lot!
Niclas

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions