- Source:
Methods
(async, static) wait(delayopt, passThroughArgopt) → {Promise.<T>}
Parameters:
Name | Type | Attributes | Default | Description |
---|---|---|---|---|
delay |
number |
<optional> |
0 | Delay in milliseconds before the returned promise resolves. If this
parameter is omitted, a value of 0 is used, meaning execute "immediately", or more
accurately, as soon as possible. Note that in either case, the actual delay may be longer
than intended (it uses |
passThroughArg |
T |
<optional> |
Pass-through argument to resolve with, can be used to insert "wait()" in a chain to pass through a value to the next promise function. |
This function returns a promise that resolves after delay
milliseconds. It resolves with
the passThroughArg
, if one is supplied, or undefined if none is supplied. Example use
case: In an IMAP message retrieval application we use this function to create a delay between
retries after disconnects from the IMAP server to avoid triggering an alert on the server for
too many and too frequent connections.
- Source:
Returns:
Type: Promise.<T>
(async, static) timeout(delayopt, promise, txtopt) → {Promise.<T>}
Parameters:
Name | Type | Attributes | Default | Description |
---|---|---|---|---|
delay |
number |
<optional> |
Infinity | Timeout in milliseconds. If the promise from the function
has not resolved by then we return a rejected promise. If this parameter is omitted the
promise is returned as-is because we assume "Infinity" as default delay value so that it is
useless to even start the timer. |
promise |
Promise.<T> | The promise that the timeout (if one is given) is applied to. |
||
txt |
string |
<optional> |
'[${delay} ms]' | Text to include in the Error message after a timeout |
This function delivers a rejection if a given promise does not resolve or reject within the given time. The advantage of using this function over using a Promise.race() of ones promise against the promise-helper wait() function above is that it cancels the timer if the promise resolves before the timer fires. While a lingering timer has no influence on the value of the promise a program won't end as long as there are timers still running - so if you have a long-running timeout your app will be running for at least that long, even if it is actually finished a split second later. Canceling the timer prevents that problem with negligible effort and no other side-effects.
IMPORTANT: A timeout does not cancel the function that created the promise! It merely returns the rejection from the timeout instead of waiting for the result of the original promise.
- Source:
Returns:
Returns the promise resulting from Promise.race
-ing the received promise
against (or with) a timeout promise. Whichever of the two is fulfilled first wins. If the
timeout promise wins the returned promise is rejected with an Error
whose name
is
"TimeoutError".
Type: Promise.<T>
(async, static) serializeWithType(type, …functions) → {Promise.<T>}
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
type |
string | The given promise-producing functions are serialized together with any
other ones we may already have serialized previously under the given |
|
functions |
function |
<repeatable> |
List of arguments of type |
Make sure the given functions are executed sequentially. The "type" argument means we can add functions later, even much later and from a completely different location in the code. The purpose may be to coordinate access to a shared external resource without having to know which part of the code uses it. We remember the chain we build for that given type string. If there is more than one function in the argument list we serialize them in the specified order. Note: If any promise in the chain is rejected (directly or by throwing an error) subsequent functions are not impacted and will still be run! The serializer's function merely is to ensure that none of the given functions are ever being executed at the same time.
- Source:
Returns:
Returns the last promise added to the chain. Anything attached via .then(..) to the returned promise is guaranteed to execute only after the chain is completed.
Type: Promise.<T>
(async, static) allSettled(promises) → {Promise.<AllSettled.<T>>}
Parameters:
Name | Type | Description |
---|---|---|
promises |
Array.<Promise.<T>> | An array of Promise objects |
Implementation of Promise.allSettled
.
This function never rejects and all promises fulfill, the fulfilled/rejected status is
instead supplied in a meta-object of the always-fulfilled promise.
NOTE: Unlike the proposed function our implementation guarantees that rejection values
are instances of Error
. By invoking our centralized createError()
when the value is not
an Error
we have a special error (with unique code) to get notified of such issues -
rejections should really always be in the form of errors, for consistency and also for the
stack trace.
- Source:
Returns:
Type: Promise.<AllSettled.<T>>
(async, static) retry(fn, optionsopt) → {Promise.<T>}
Parameters:
Name | Type | Attributes | Description | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
fn |
function | A function of type |
||||||||||||||||||||||||||
options |
object |
<optional> |
Properties
|
The function returning a promise is executed again when the promise rejects until it either resolves or the maximum number of retries is reached.
- Source:
Returns:
Resolves with whatever the given function fn returns
Type: Promise.<T>
(static) createTrackingPromise() → {TrackingPromiseObj.<T>}
This function creates a "passive tracking promise".
Usage
This function returns the promise as well as its resolve/reject callbacks, normally hidden inside the promise and used by code normally run through the promise, which a tracking promise does not have.
You keep the promise and give the resolve/reject callbacks to the function that you want to track, where previously you would have gotten an event emitter to subscribe to or given a callback function to. That code, instead of emitting an event or calling your callback function, now calls the resolve or the reject callback of the promise.
Explanation
Normally promises control all the code that produces their success or failure result. This tracking promise however does not.
Tracking promises are useful when a "3rd party" otherwise not involved with direct control wants to know the final outcome of an asynchronous procedure. For example, if we have a stream the code controlling the stream will not use a promise. There may however be a third party that only wants to know when the stream ends but does not care what happens during the stream.
While we could expose the details of the stream, the "error" event and the "finish" (or "end") events, for example, we find it much more convenient and also a nice abstraction across more than just streams to use this tracking promise device.
In addition, unlike event handlers the promise keeps the state once it has been set, so subscribing after the state-changing event already happened still gives the correct result. If we rely on event handlers instead we would have to have an additional public property or method to access the current state.
Errors reported through the tracking promise also may not be the actual errors but a generic one, after all, code using the tracking promise is not involved in any details.
The procedure to create a tracking promise is bloody: The visceral functions usually hidden deep inside the promise's peritoneum are forcefully exposed to the outside, one might say the whole promise is turned inside out. We know this is not "standard" but after giving it a lot of thought we still find the concept appealing for the given use case.
Default rejection handler
Tracking promises receive a default rejection catch()
handler that discards and ignores any
errors.
This has no influence if any handler, for rejection or for success, is attached to the promise at all.
It is used only in case the tracking promise is not used, if nothing is attached to it. This can happen, for example, if a tracking promise is an optional property in an API-object to indicate overall end with failure or success of a process. We use it for file streams on the system level, for example.
If the promise is used this default handler has no function and does not influence the behavior of the promise. That means any rejection handler will still catch the rejection, and any success handler creates a new promise that might reject if the underlying promise rejects and therefore always needs to be coupled with a rejection handler as usual, see https://stackoverflow.com/questions/42460039/promise-reject-causes-uncaught-in-promise-warning for an explanation.
Reasons for a tracking promise:
-
Hide internals: Is it an event based process like a stream, or something completely custom? It does not matter, if it fits the pattern "some async. process we are not involved in but would like to know when it ends - transmitting a result or failure is an additional feature.
-
Code that already uses promises or async/await to coordinate asynchronous activities can seamlessly use the promise instead of having extra (non-promise) code mixed with the promise-based one.
-
Tracking promises are used in place of events (error, end) or callbacks. When the asynchronous process uses those, but the code that wants either or both of 1) synchronization and 2) the result (success value, error) without controlling the process (in which case there would be no choice) may prefer a promise.
When not to use a tracking promise:
-
The code that wants to use a tracking promise is actually directly responsible for the asynchronous process. In that case it should use the actual constructs (e.g. events).
-
When it doesn't feel right :-)
- Source:
Returns:
Returns an object with the tracking promise and its resolve
and reject
methods
Type: TrackingPromiseObj.<T>
Type Definitions
PromiseResolveCb(valueopt) → {undefined}
Parameters:
Name | Type | Attributes | Description |
---|---|---|---|
value |
Promise.<T> | T |
<optional> |
The value the promise will be resolved with |
Type describing the resolve() callback function received by the new Promise()
creation
callback function.
Copied from TypeScript's lib.es2015.promise.d.ts
- Source:
Returns:
Returns undefined
Type: undefined
PromiseRejectCb(reason) → {undefined}
Parameters:
Name | Type | Description |
---|---|---|
reason |
Error | The error the promise is rejected with |
Type describing the reject() callback function received by the new Promise() creation callback function. Copied from TypeScript's lib.es2015.promise.d.ts
- Source:
Returns:
Returns undefined
Type: undefined