AsyncSteps loops
Loop is a fundamental programming concept. However, it requires special approach to mimic that on async callbacks with proper memory management.
Luckily, FutoIn AsyncSteps provide a set of loop types with proper break
and continue
commands.
for (;;) {}
Generic infinite loop: Such loop is usually used in persistent service “threads” or when limit of async requests is not known in advance.
asi.loop( (asi) => {
if (some_condition) {
asi.break(); // throws special exception
}
// do something
if (some_other_cond) {
as.continue(); // throws special exception
}
// do something more
} );
for (i = 0; i < N; ++i) {}
Repeat loop: Such loop is used when maximum number of iterations is known in advance.
asi.repeat( 3, (asi, i) => {
console.log( i ); // 0, 1, 2
// executed 3 times (max)
} );
for ( [k, v] of array_or_object_items) {}
For-each loop: Such loop is very handy to iterate over array or object.
const obj = { a: 1, b: 2, c: 3 };
asi.forEach( obj, (asi, k, v) => {
console.log( `${k}=${v}` );
// a=1, b=2, c=3
} );
const arr = [ 1, 2, 3 ];
asi.forEach( arr, (asi, k, v) => {
console.log( `${k}=${v}` );
// 0=1, 1=2, 2=3
} );
Inner loops and labels
There is a known inner loop break/continue problem. It is safely
solved by labels. So, each AsyncSteps loop function supports optional
string label. The labels can be used in asi.break()
and asi.continue()
.
asi.loop( (asi) => {
// outer loop body
asi.repeat( 10, (asi, i) => {
// middle loop body
asi.forEach( [1, 2, 3], (asi, k, v) => {
/// inner loop body
if ( i > 5 ) {
as.break( 'OUTER' );
// exit all three loops
} else {
as.continue( 'MIDDLE' );
// continue in the middle loop
}
}, 'INNER' );
}, 'MIDDLE' );
}, 'OUTER' );