Asynchro

Asynchro

⇝ Manages multiple async function/await tasks that can be ran in series/sequential and/or parallel/concurrent order in relation to one another. See started for more details.

Constructor

new Asynchro(resultopt, throwsopt, logopt, includeErrorMsgCheckopt)

Constructor

Source:
Parameters:
Name Type Attributes Description
result Object <optional>

the object used for storing results (omit to prevent capturing of results)

throws Boolean | Object | String <optional>

one of the following values (unless superseded, will be applied to all queued tasks):

  • true to throw any errors and instantly stop any further execution
  • false to catch any errors that are thrown
  • Object an object containing the following properties:
    • invert true to catch errors when matches are made, false/omit to throw errors when matches are made
    • matches An array that contains any of the following:
      • system A string value equal to "system" that will match when an error is a type within Asynchro.systemErrorTypes
      • Object An object that contains property names/values that will be matched against property name/values in the caught error. When invert is true, all names/values on the caught error must match the names/values on the object in order to be caught/captured in Asynchro.errors. When invert is false/omitted, all names/values on the caught error must match all of the names/values on the object in order to be rethrown.
  • system a single matches string (invert defaults to false)

Re-thrown errors will set Error.cause to the originally thrown error.

log function <optional>

function(tagArray, object) that will log process output (omit to prevent logging)

includeErrorMsgCheck function <optional>

A function(name, operation, error) that will return true when the error message should be included in the final Asynchro.messages output (defaults to false)

Members

(static) DEFAULT_SYSTEM_ERROR_TYPES :Array.<function()>

The default system error types that will be used for the system error type

Source:
Type:
  • Array.<function()>

(static) FAILED :String

The status indicating that the queue was ran, but failed to complete

Source:
Type:
  • String

(static) QUEUEING :String

The status indicating that the queue is available for tasks to be added and is waiting to be ran

Source:
Type:
  • String

(static) RUNNING :String

The status indicating that the queue is sealed from adding new tasks and is waiting to complete

Source:
Type:
  • String

(static) STOPPED :String

The status indicating that the queue has been stopped before completing

Source:
Type:
  • String

(static) SUCCEEDED :String

The status indicating that the queue has successfully ran to completion

Source:
Type:
  • String

(static) TRANSFERRED :String

The status indicating that the queue has been transferred to another queue before completing

Source:
Type:
  • String

count :Integer

The total number of tasks queued for execution

Source:
Type:
  • Integer

endHandler

Registers a handler function that will be executed once Asynchro.run has completed. Only one handler is allowed per instance and will overwrite any end handler that has been previously been set.

Source:

errors :Array.<Error>

An immutable array of all the caught errors encountered during execution

Source:
Type:
  • Array.<Error>

result :Object

The result of all of the cumulative execution results that had designated names assigned

Source:
Type:
  • Object

status :String

The current execution status

Source:
Type:
  • String

systemErrorTypes :Array.<function()>

An immutable array of error type constructs that will be thrown when they are encountered during queue execution using instanceof on the thrown error (used by system values for throwing in Asynchro.throwsError)

Source:
Type:
  • Array.<function()>

waiting :Integer

The number of tasks queued that are waiting for execution excluding Asynchro.background tasks (see Asynchro.waitingBackground).

Source:
Type:
  • Integer

waitingBackground :Integer

The number of Asynchro.background tasks queued that are waiting for execution. NOTE: If Asynchro.backgroundWaiter is never called the count will remain indefinitely.

Source:
Type:
  • Integer

Methods

(static) extractFuncArgs(fn) → {Array.<String>}

Extracts the argument names that a function accepts

Source:
Parameters:
Name Type Description
fn function

The function to extract paramter names from

Returns:
Type:
Array.<String>

The array of function parameter names in the order that they are defined

(static) promisifyCallback(obj, funcName, funcParamsopt) → {function}

Takes an object's function with the last argument being a callback function which accepts multiple parameter arguments (1st argument being an Error) and converts it to a promise. Rejects when an Error is passed in as the first argument or resolves using the arguments passed into the callback (excluding the 1st error parameter). Also supports this reference within the passed function (set to the passed obj)

Source:
Parameters:
Name Type Attributes Description
obj Object

The object that contains the function that will be promisfied

funcName String

The name of the function property in the obj

funcParams Array.<String> | function <optional>

A String[] of parameter names for the given function that will be used as the property names on the resolved promise object (should not include the error or callback parameter names), a Function to extract the property names from, or omit/false to simply use an array of argument values when resolving the promise

Returns:
Type:
function

A function(..args) that returns a promise

(static) promisifyEventTarget(target, tkoopt, eventMaxopt, eventErrorMaxopt, implyErroropt, resolveOnTimeoutopt) → {function}

Promisifies event(s) fired from a event target

Source:
Parameters:
Name Type Attributes Default Description
target Object

The object that will fire event(s)

tko Integer <optional>
60000

The timeout delay in milliseconds to wait for the event before rejecting or resolving the promise (set to zero for unlimited timeout or override using events[].tko)

eventMax Integer <optional>
1

The number of times any one of the events must fire before the promise is resolved

eventErrorMax Integer <optional>
1

Rhe number of times any one of the events must fire that contain an Error as the first argument before the promise is rejected with that Error (or Error[] if there are more than one)

implyError Boolean <optional>
true

true will automatically listen for an error events that will reject or resolve

resolveOnTimeout Boolean <optional>
false

true to resolve when the tko timeout is reached, false to reject and uses the passed tko for the timeout delay

Returns:
Type:
function

The function that will listen for events to fire before resolving/rejecting with either an array of arguments passed into the listener, a single value when the listener was passed one argument, undefined when the listener was not passed any arguments or an Object generated using listenerParams to map the argument values passed into the listener in the order they are received. The function accepts the following arguments:

  • event either the event name that will be listened to or an object that will override
  • listenerParams an optional String[] of parameter names for the given function that will be used as the property names on the resolved promise object (or Object[] when eventMax > 1), a Function to extract the property names from, or omit/false to simply use an array of argument values when resolving the promise
Examples
// 30 sec timeout, 1 event max (default), 1 error event max (default)
const listenAsync = Asynchro.promisifyEventTarget(myEventTarget, 30000);
setTimeout(() => {
 myEventTarget.dispatchEvent('my-event-1', 'done');
 myEventTarget.dispatchEvent('my-event-2', 1, 2, 3);
 myEventTarget.dispatchEvent('my-event-2', 4, 5, 6);
 // my-event-2 will never set the following since it exceeds event max of 1
 myEventTarget.dispatchEvent('my-event-2', 'not set');
 myEventTarget.dispatchEvent('my-event-3', 1, 2, 3);
 myEventTarget.dispatchEvent('my-event-4', 'a', 'b', 'c');
 myEventTarget.dispatchEvent('my-event-4', 'd', 'e', 'f');
}, 10);
// run in parallel
const p1 = listenAsync('my-event-1');
const p2 = listenAsync({ name: 'my-event-2', eventMax: 2 });
const p3 = listenAsync('my-event-3', ['one', 'two', 'three']);
const p4 = listenAsync({ name: 'my-event-4', eventMax: 2 }, ['name1', 'name2', 'name3']);
const p4x = listenAsync({ name: 'my-event-4', eventMax: 2 }, function demoNames(name1, name2, name3){});
console.log(await p1); // done
console.log(await p2); // [[1, 2, 3], [4, 5, 6]]
console.log(await p3); // { one: 1, two: 2, three: 3 }
console.log(await p4); // [{ name1: 'a', name2: 'b', name3: 'c' }, { name1: 'd', name2: 'e', name3: 'f' }]
console.log(await p4x); // [{ name1: 'a', name2: 'b', name3: 'c' }, { name1: 'd', name2: 'e', name3: 'f' }]
// example setup
const tko = 30000, delay = 10, a = 1, b = 2, c = 3, d = 4, e = 5, l1 = 200, l2 = 300;
function multiply(a, b, c) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ m1: 10 * (a || 0), m2: 20 * (b || 0), m3: 30 * (c || 0) });
    }, delay);
  });
}
// class just for example purposes
class MyEventTarg {
  constructor() {
    this.listeners = {};
  }
  addListener(event, listener) {
    this.listeners[event] = this.listeners[event] || [];
    this.listeners[event].push(listener);
  }
  removeListener(event, listener) {
    var idx = -1;
    if (!(event in this.listeners)) idx;
    for (let lsn of this.listeners[event]) if (++idx && lsn === listener) {
      this.listeners[event].splice(idx, 1);
      return idx;
    }
  }
  dispatchEvent(type) {
    if (this.listeners[type]) {
      // pass all the args to the listener except the 1st arg that is the event name
      const args = Array.prototype.slice.call(arguments, 1);
      for (let lsn of this.listeners[type]) lsn.apply(this, args);
    }
  }
}
const trg = new MyEventTarg();

// 30 sec timeout, 1 event max (default), 1 error event max (default)
const listenAsync = Asynchro.promisifyEventTarget(trg, tko);
const ax = new Asynchro({});
ax.parallel('one', multiply, a, b, c);
ax.series('two', listenAsync, 'event-1');
ax.series('three', multiply, d, e);
ax.parallel('four', listenAsync, 'event-2');

setTimeout(() => {
  trg.dispatchEvent('event-1', l1);
  setTimeout(() => {
    trg.dispatchEvent('event-2', l2);
  }, delay * 2); // delay must be between delay on "two"/"three" and "tko"
}, delay); // delay must be between delay on "two" and "tko" ("one" is in parallel)

const rslt = await ax.run();
// { one: { m1: 10, m2: 40, m3: 90 }, two: 200, three: { m1: 40, m2: 100, m3: 0 }, four: 300 }
console.log(rslt);

arg(name) → {ResultArg}

Resolves to a previously completed result value from a queued task function so the results from one task can be passed into subsequent tasks during execution via Asynchro.run

Source:
Parameters:
Name Type Description
name String

The name given for the task where the result will be stored as a property of the Asynchro.result object. Can use dot notation to express a path to other objects (e.g. someObject.someOtherObject.someValue would equate to asynchro.result.someObject.someOtherObject.someValue once the queued task function is executed)

Returns:
Type:
ResultArg

The ResultArg

Example
const ax = new Asynchro({});
ax.series('one', async () => {
 // other async operations here
 return { array: [1] };
});
ax.series('two', async (a) => {
 // other async operations here
 console.log(a); // prints out 1
}, ax.arg('one.array[0]'));
await ax.run();

background(nameopt, fn, …args) → {String}

Queues an async function to run in the background (i.e. the queue wont wait for the results and will not be captured). Thrown errors within the scope of specified throws flag(s) will be thrown and will stop further execution of the queue.

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task that can be used in conjunction with Asynchro.verify (no results will be set from the function's return value - omit will cause the name/ID will be generated and returned)

fn function

The function to queue for asynchronicity

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

backgroundThrowsOverride(nameopt, throwsopt, fn, …args) → {String}

Queues an async function to run in the background (i.e. the queue wont wait for the results and will not be captured). Thrown errors within the scope of specified throws flag(s) will be thrown and will stop further execution of the queue.

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task that can be used in conjunction with Asynchro.verify (no results will be set from the function's return value - omit will cause the name/ID will be generated and returned)

throws Boolean | Object | String <optional>

One of the following values (supersedes any throws parameters passed during construction):

  • true to throw any errors and instantly stop any further execution
  • false to catch any errors that are thrown
  • Object an object containing the following properties:
    • invert true to catch errors when matches are made, false/omit to throw errors when matches are made
    • matches An array that contains any of the following:
      • system A string value equal to "system" that will match when an error is a type within Asynchro.systemErrorTypes
      • Object An object that contains property names/values that will be matched against property name/values in the caught error. When invert is true, all names/values on the caught error must match the names/values on the object in order to be caught/captured in Asynchro.errors. When invert is false/omitted, all names/values on the caught error must match all of the names/values on the object in order to be rethrown.
  • system a single matches string (invert defaults to false)

Re-thrown errors will set Error.cause to the originally thrown error.

fn function

The function to queue for asynchronicity

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

(async) backgroundWaiter(resultObjopt) → {Asynchro}

Waits for any pending Asynchro.background functions to complete and captures the results/caught errors.

Source:
Parameters:
Name Type Attributes Default Description
resultObj Object | Boolean <optional>
true

Either the object where the background results will be set or true to use the Asynchro.result (may be from a different Asynchro instance when branching). Each property name that matches the name passed into the original call to Asynchro.background that queued the background function will be set on the result object.

Returns:
Type:
Asynchro

Either the Asynchro instance that the backgroundWaiter was called from, or the last Asynchro instance returned in the chain of branching/transfer operations using Asynchro.verify

Example
const ax = new Asynchro({});
ax.background('myBgTask', myAsyncFunc, myAsyncFuncArg1, myAsyncFunc2);
// ...other queued tasks?
await ax.run();
// now that Asynchro.run has completed we can optionally wait for the background tasks to complete
// NOTE: awlays use return Asynchro instance in case branching took place
const abx = await ax.backgroundWaiter();
// if errors are caught, should print out errors thrown from the background async function
for (let error of abx.errors) console.error(error);
// if no error for myBgTask, should print out the return value from the background async function
console.log(abx.result.myBgTask);

messages(delimiteropt) → {String}

The accumulated message(s) gathered while running queued tasks during a Asynchro.run

Source:
Parameters:
Name Type Attributes Description
delimiter String <optional>

The delimter to use between messages

Returns:
Type:
String

The cumulative messages

parallel(nameopt, fn, …args) → {String}

Queues an async function to run in parallel relative to other functions in the queue

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task where the result will be stored as a property of the Asynchro.result object (omit to prevent results from being set from function return value - a name/ID will be generated and returned)

fn function

The function to queue for asynchronicity

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

parallelThrowOverride(nameopt, throwsopt, fn, …args) → {String}

Queues an async function to run in parallel relative to other functions in the queue while overriding the throws option set during construction.

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task where the result will be stored as a property of the Asynchro.result object (omit to prevent results from being set from function return value - a name/ID will be generated and returned)

throws Boolean | Object | String <optional>

One of the following values (supersedes any throws parameters passed during construction):

  • true to throw any errors and instantly stop any further execution
  • false to catch any errors that are thrown
  • Object an object containing the following properties:
    • invert true to catch errors when matches are made, false/omit to throw errors when matches are made
    • matches An array that contains any of the following:
      • system A string value equal to "system" that will match when an error is a type within Asynchro.systemErrorTypes
      • Object An object that contains property names/values that will be matched against property name/values in the caught error. When invert is true, all names/values on the caught error must match the names/values on the object in order to be caught/captured in Asynchro.errors. When invert is false/omitted, all names/values on the caught error must match all of the names/values on the object in order to be rethrown.
  • system a single matches string (invert defaults to false)

Re-thrown errors will set Error.cause to the originally thrown error.

fn function

The function to queue for asynchronicity

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

(async) run() → {Object}

A one-time execution run of all queued asynchronous functions in insertion order with parallel/concurrent running simultaneously and series tasks running in succession. Any queued Asynchro.background tasks will continue to run after Asynchro.run completes, possibly accumulating additional Asynchro.errors as those tasks complete (see Asynchro.backgroundWaiter to wait for any background tasks to finish completing).

Source:
Returns:
Type:
Object

The result from Asynchro.result

series(nameopt, fn, …args) → {String}

Queues an async function to run in series relative to other functions in the queue

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task where the result will be stored as a property of the Asynchro.result object (omit to prevent results from being set from function return value - a name/ID will be generated and returned)

fn function

The function to queue for asynchronicity (can also be a synchronous function)

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

seriesThrowOverride(nameopt, throwsopt, fn, …args) → {String}

Queues an async function to run in series relative to other functions in the queue while overriding the throws option set during construction.

Source:
Parameters:
Name Type Attributes Description
name String <optional>

The name given for the task where the result will be stored as a property of the Asynchro.result object (omit to prevent results from being set from function return value - a name/ID will be generated and returned)

throws Boolean | Object | String <optional>

One of the following values (supersedes any throws parameters passed during construction):

  • true to throw any errors and instantly stop any further execution
  • false to catch any errors that are thrown
  • Object an object containing the following properties:
    • invert true to catch errors when matches are made, false/omit to throw errors when matches are made
    • matches An array that contains any of the following:
      • system A string value equal to "system" that will match when an error is a type within Asynchro.systemErrorTypes
      • Object An object that contains property names/values that will be matched against property name/values in the caught error. When invert is true, all names/values on the caught error must match the names/values on the object in order to be caught/captured in Asynchro.errors. When invert is false/omitted, all names/values on the caught error must match all of the names/values on the object in order to be rethrown.
  • system a single matches string (invert defaults to false)

Re-thrown errors will set Error.cause to the originally thrown error.

fn function

The function to queue for asynchronicity

args * <repeatable>

Aguments that will be passed into the queued function

Returns:
Type:
String

The queued name/ID (either passed or generated)

throwsError(errorOrType, throwWhenTrueopt) → {Boolean}

Determines if an Error or a Function construct to an Error will be thrown when encountered during an execution run

Source:
Parameters:
Name Type Attributes Description
errorOrType Error | function

Either an Error or a Function construct to an Error

throwWhenTrue Boolean <optional>

true to actually throw the error when errorOrType is an actual Error and it is determined that the error should throw

Returns:
Type:
Boolean

Returns true if the Error or Function construct to an Error will be thrown when encountered during an execution run

verify(name, fn)

Each verify is an async function that will be called after the queued task that matches the registered name has ran. It's important to note that parallel tasks will call the registered verify function TWICE. Once when the async function is invoked (isPending === true) and antoher time when await completes (isPending !== true). There is only one verify per registered name. So, registering verify multiple times for the same name will overwrite any verify functions that were set by previous calls.

Source:
Parameters:
Name Type Description
name String

Either the name designated as the property name or the Function.name from the function used when calling parallel or series

fn function

An async function that will accept a single object argument that contains the follwing properties:

  1. error A mutable error object that occurred during execution of the queued task (changes to this value will be reflected in the final Asynchro.result or re-thrown depending on the rules/throws set for re-throwing/catching defined on the corresponding queued task). Setting the error will have the same effect as throwing an Error from within the verify function.
  2. result A mutable result value returned from the queued task execution (changes to this value will be reflected in the final Asynchro.result).
  3. isPending An immutable boolean value indicating the task has not yet returned from await. The value will always be false for series tasks since they await before calling the verify. When a parallel task is called, but not yet returned from await the value will be true. In the subsequent parallel call to the verify function the value will be false since await has completed. When background tasks are called the value will always be true since they will never await on the task to complete.
  4. isParallel An immutable boolean value indicating if the task was ran in parallel or series
  5. isBackground An immutable boolean value indicating if the task was ran in the background (i.e. calls the task without await)
  6. event An immutable event name defined when the task originated from the function returned by Asynchro.promisifyEventTarget
  7. name An immutable string value reflecting the original name passed into Asynchro.verify
  8. operation An immutable string value reflecting the original function name of the function passed into Asynchro.verify
  9. message A write-only mutable string value that will override the default message that will be added to Asynchro.messages

The return value should be one of the following:

  1. false will stop execution of pending tasks that have been queued and Asynchro.status will be set to Asynchro.STOPPED.
  2. Another Asynchro instance that will cause the current queue to stop while the new queue will take over via await Asynchro.run. Asynchro.status will be set to Asynchro.TRANSFERRED with any Asynchro.messages and/or Asynchro.errors being appended to the new queue instance. Also, Asynchro.result will be merged into the new queue instance.
  3. Any other value will have no impact.

The verify this reference will point to the Asynchro instance

NOTE: There may be some residuale parallel/concurrent/background functions that were already running prior to the queue being stopped that may still be running after a queue has been stopped/transferred by verify.


4.0.0 (2019-12-20)

Full Changelog

Features: