@dizmo/functions-queued
Provides two functions queued
and auto
, where the latter can also be accessed via queued.auto
. The queued
function takes as argument another function e.g. fn
, which is then queued for execution. During its invocation fn
receives an extra argument – a next
function – which needs to be invoked within the body of fn
to continue processing the queue.
The queued
function creates a separate queue defined by the name of the provided function: This means that if multiple functions e.g. f1
and f2
need to be queued together, then they need to be wrapped with functions using the same name (e.g. fn
). If only anonymous functions are provided then the internal queue is named with a random identifier.
Functions with the same name will be put into the same queue, and class methods with the same class plus method name will also be put into the same queue!
The auto
function takes a boolean flag and returns then a queue e.g. qn
(for the provided function). If the flag is set to true
then the queue start dequeueing immediately, and otherwise qn.next
is required to be invoked to trigger dequeueing; by default queued
starts dequeueing immediately.
Both the queued
and auto
functions accepts options, which enable dequeueing (a)synchronously and also support a mechanism to acquire and release (global) locks. By default dequeueing is performed synchronously without the usage of a lock. Also, an option to limit the maximum queue size can provided.
Further, by using a @queued.decorator
, class methods can be decorated to turn them into queues, where the same naming rules as explained above apply. However, each method name is prepended with the corresponding class name; i.e. two methods with the same name but from to differently named classes will be put into to different queues.
Instead of using the provided next
function to continue dequeueing, the wrapped function can also return a promise for a truthy value. Also, the returned value can be accessed upon awaiting the promise returned by the invocation of the wrapped function.
Usage
Install
npm install @dizmo/functions-queued --save
Require
const { queued } = require('@dizmo/functions-queued');
Examples (functions)
import { queued } from '@dizmo/functions-queued';
next
(and auto=true
):
Dequeue with const fn = queued(function fn(
n: number, next: Function
) {
setTimeout(next, 200);
});
fn(1); fn(2); const result = await fn(3);
next
(and auto=false
):
Dequeue with const qn = queued.auto(false)((
...args: any[]
) => {
const next = args.pop() as Function;
setTimeout(next, 200);
});
qn(1); qn(1, 2); qn(1, 2, 3); qn.next();
Promise
(and auto=true
):
Dequeue with const gn = queued(function gn(
n: number
) {
return Promise.resolve(true);
});
gn(1); gn(2); const result = await gn(3);
Promise
(and auto=false
):
Dequeue with const qn = queued.auto(false)((
...args: any[]
) => {
return new Promise((resolve) => {
setTimeout(() => resolve(true), 200);
});
});
qn(1); qn(1, 2); qn(1, 2, 3); qn.next();
Examples (functions) with queue size
Promise
(and size=0
):
Dequeue with const gn = queued(function gn(
n: number
) {
return Promise.resolve(true);
}, {
size: 0
});
gn(1); // throws QueueError('full')
Promise
(and size=1
):
Dequeue with const gn = queued(function gn(
n: number
) {
return Promise.resolve(true);
}, {
size: 1
});
gn(1); // throws QueueError('full')
Promise
(and size=2
):
Dequeue with const gn = queued(function gn(
n: number
) {
return Promise.resolve(true);
}, {
size: 2
});
gn(1); gn(2); gn(3); // throws QueueError('full')
Promise
(and size=3
):
Dequeue with const gn = queued(function gn(
n: number
) {
return Promise.resolve(true);
}, {
size: 3
});
gn(1); gn(2); gn(3); gn(4); // throws QueueError('full')
Examples (functions) with locking
next
(and auto=true
) plus a lock:
Dequeue with const fn = queued(function fn(
n: number, next: Function
) {
setTimeout(next, 200);
}, {
sync: true, // dequeue synchronously [default]
lock: {
// acquire (pseudo) lock [default]
acquire: () => Promise.resolve(true),
// release (pseudo) lock [default]
release: () => Promise.resolve(true)
}
});
fn(1); fn(2); const result = await fn(3);
Promise
(and auto=false
) plus a lock:
Dequeue with const qn = queued.auto(false)((
...args: any[]
) => {
return new Promise((resolve) => {
setTimeout(() => resolve(true), 200);
});
}, {
sync: false, // dequeue asynchronously [*not* default]
lock: {
// acquire (pseudo) lock [default]
acquire: () => Promise.resolve(true),
// release (pseudo) lock [default]
release: () => Promise.resolve(true)
}
});
qn(1); qn(1, 2); qn(1, 2, 3); qn.next();
Examples (class methods)
import { queued } from '@dizmo/functions-queued';
next
(and auto=true
):
Dequeue with class AClass {
@queued.decorator
public method(
n: number, next?: Function
) {
if (next) setTimeout(next, 200);
}
}
const obj = new AClass();
obj.method(1); obj.method(2); const result = await obj.method(3);
next
(and auto=false
):
Dequeue with class BClass {
@queued.decorator(false)
public method(
n: number, next?: Function
) {
if (next) setTimeout(next, 200);
}
}
const obj = new BClass();
obj.method(1); obj.method(2); obj.method(3); obj.method.next();
..where in TypeScript casting obj.method
to any
might be required to access the next
method.
Promise
(and auto=true
):
Dequeue with class CClass {
@queued.decorator
public method(
n: number
) {
return Promise.resolve(true);
}
}
const obj = new CClass();
obj.method(1); obj.method(2); const result = await obj.method(3);
Promise
(and auto=false
):
Dequeue with class DClass {
@queued.decorator(false)
public method(
n: number
) {
return Promise.resolve(true);
}
}
const obj = new DClass();
obj.method(1); obj.method(2); obj.method(3); obj.method.next();
..where in TypeScript casting obj.method
to any
might be required to access the next
method.
Development
Clean
npm run clean
Build
npm run build
without linting and cleaning:
npm run -- build --no-lint --no-clean
with UMD bundling (incl. minimization):
npm run -- build --prepack
with UMD bundling (excl. minimization):
npm run -- build --prepack --no-minify
Lint
npm run lint
with auto-fixing:
npm run -- lint --fix
Test
npm run test
without linting, cleaning and (re-)building:
npm run -- test --no-lint --no-clean --no-build
Cover
npm run cover
without linting, cleaning and (re-)building:
npm run -- cover --no-lint --no-clean --no-build
Documentation
npm run docs
Publish
npm publish
initially (if public):
npm publish --access=public
Copyright
© 2021 dizmo AG, Switzerland