AsyncSteps interoperability with other async implementations
Please read timeout & cancel first as
asi.setTimeout()
, asi.setCancel()
and asi.waitExternal()
are
used to signal AsyncSteps to disable implicit asi.success()
call
and wait for external event completion.
Generic approach
Please note that callbacks from external functionality are NOT called through AsyncSteps. Therefore, we have to:
- Check that related AsyncSteps instance is still running.
- Catch and discard errors thrown by
asi.error()
to avoid unhandled exception warnings. - Explicitely call
asi.success()
.
asi.add( (asi) => {
asi.waitExternal(); // disable implicit success()
some_obj.read( (err, data) => {
if (!asi.state) {
// ignore as AsyncSteps execution got canceled
} else if (err) {
try {
asi.error( 'IOError', err );
} catch (_) {
// ignore error thrown as there are no
// AsyncSteps frames on stack.
}
} else {
asi.success( data );
}
} );
} );
Time limit
asi.add( (asi) => {
asi.setTimeout( 10e3 ); // also disables implicit success
some_obj.read( (err, data) => {
// ... same as in the generic example
} );
} );
Cancellation callback
In many cases, we want to disable external processing ASAP, if we going to discard its result any way.
asi.add( (asi) => {
const req = some_obj.read( (err, data) => {
// ... same as in the generic example
} );
// Make sure to cancel read on error or cancel.
// Also disables implicit success.
this.setCancel( (asi) => some_obj.cancelReq( req ) );
} );
ES6 Promise interoperation
Since FTN12 v1.11, it’s very easy to add Promise or async
function
call as one of steps.
Since FTN12 v1.12, it’s also possible to use AsyncSteps as Promise by
using #promise()
instead of #execute()
.
$as
.add((asi) => {
// await Promise
as.await(
new Promise( ... ),
(as, reason) => {
// handle rejection reason
}
);
// Normal Step
as.add( ( asi, result ) => {
// next step with resolved result
as.success( result );
} );
})
// Wrap in Promise
.promise()
.then((result) => {}, (error) => {} );
Additional notes
It’s allowed and encouraged to use both asi.setTimeout()
and
asi.setCancel()
when external event processing is used to make
sure that external event has some time limit and that external
processing is correctly aborted.
It’s recommended to wrap external event processing in libraries to make the code cleaner and more safe.
Example: futoin-request