![Oracle Drags Its Feet in the JavaScript Trademark Dispute](https://cdn.sanity.io/images/cgdhsj6q/production/919c3b22c24f93884c548d60cbb338e819ff2435-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Oracle Drags Its Feet in the JavaScript Trademark Dispute
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
flowless is not a flawless :)
Here is the same example as asyncblock.
var fs = require('fs');
var flowless = require('flowless');
flowless.runSeq([
flowless.par([
[fs.readFile, 'path1', 'utf8'],
[fs.readFile, 'path2', 'utf8']
]),
function(results, cb) {
fs.writeFile('path3', results.join(''), cb);
},
[fs.readFile, 'path3', 'utf8']
], function(err, result) {
if (err) throw err;
console.log(result);
console.log('all done');
});
$ npm install flowless
flowless provides two kind of API for control-flow.
runSeq()
, runPar()
and runMap()
.seq()
, par()
and map()
.The former is similar to the function that other control-flow modules (e.g. Async) provide.
On the other hand, the latter returns a function which runs asynchronous functions, rather than running them immediately. Because the returned function is also an asynchronous style, they are easily nestable.
Example:
var flowless = require('flowless');
flowless.runSeq([
function one() {...},
function two() {...},
flowless.par([
flowless.seq([
function three() {...},
function four() {...},
]),
flowless.seq([
function five() {...},
function six() {...},
])
]),
flowless.map(
function seven() {...}
),
function eight() {...}
], function allDone() {...}
);
The structure of this program reflects a control-flow directly.
+-> seven -+
+-> three --> four -+ +-> seven -+
one --> two -+ +--+-> seven -+-> eight --> allDone
+-> five --> six -+ +-> seven -+
...
Example:
function foo() {
return flowless.seq([
function(...) {...},
function(...) {...},
...
]);
}
function bar() {
return flowless.par([
function(...) {...},
function(...) {...},
...
]);
}
You can put them together as follows.
flowless.runSeq([
foo(),
bar()
], function(err, result) {
...
});
When an error is passed to a callback.
flowless.runSeq([
function foo(cb) {
cb(null);
},
function bar(cb) {
cb(new Error('bar faild')); // Error is passed to cb
},
function baz(cb) {
assert.fail('unreachable');
}
], function allDone(err, result) {
console.log(err);
});
When an exception is thrown.
flowless.runSeq([
function foo(cb) {
cb(null);
},
function bar(cb) {
throw new Error('bar faild'); // Error is thrown
},
function baz(cb) {
assert.fail('unreachable');
}
], function allDone(err, result) {
console.log(err);
});
In both of the cases, three()
is not called and Error
is passed to
the allDone()
.
Flowless wraps the cause error. It has the information about the location in the control-flow that the error occurred.
Example:
var flowless = require('flowless');
flowless.runSeq([
function foo(cb) {
cb(null);
},
flowless.seq([
function bar(cb) {
cb(new Error('Oooops!!'));
}
]),
], function(err, result) {
console.log(err);
});
Result:
{ [Error: seq[0] at (/tmp/error.js:6) failed: [Error: Oooops!!]]
cause: [Error: Oooops!!],
history:
[ { operator: 'seq',
index: 0,
location: '(/tmp/error.js:6)',
reason: 'failed' },
{ operator: 'runSeq',
index: 1,
location: '(/tmp/error.js:2)',
reason: 'failed' } ] }
If NODE\_DEBUG
environment variable contains flowless
,
flowless outputs logs for debug.
For example, the first example of this page, it is output log as follows:
$ NODE_DEBUG=flowless node ex.js
FLOWLESS: BEGIN runSeq at (/tmp/ex.js:4)
FLOWLESS: begin runSeq[0] at (/tmp/ex.js:4) with: [ [Function: next] ]
FLOWLESS: BEGIN par at (/tmp/ex.js:5)
FLOWLESS: begin par[0] at (/tmp/ex.js:5) with: [ [Function], 'path1', 'utf8' ]
FLOWLESS: begin par[1] at (/tmp/ex.js:5) with: [ [Function], 'path2', 'utf8' ]
FLOWLESS: end par[0] at (/tmp/ex.js:5) with: [ null, 'aaa\nbbb\nccc\n' ]
FLOWLESS: end par[1] at (/tmp/ex.js:5) with: [ null, 'xxx\nyyy\nzzz\n' ]
FLOWLESS: END par at (/tmp/ex.js:5) with: [ 'aaa\nbbb\nccc\n', 'xxx\nyyy\nzzz\n' ]
FLOWLESS: end runSeq[0] at (/tmp/ex.js:4) with : [ null, [ 'aaa\nbbb\nccc\n', 'xxx\nyyy\nzzz\n' ] ]
FLOWLESS: begin runSeq[1] at (/tmp/ex.js:4) with: [ [ 'aaa\nbbb\nccc\n', 'xxx\nyyy\nzzz\n' ], [Function: next] ]
FLOWLESS: end runSeq[1] at (/tmp/ex.js:4) with : [ null ]
FLOWLESS: begin runSeq[2] at (/tmp/ex.js:4) with: [ [Function: next] ]
FLOWLESS: end runSeq[2] at (/tmp/ex.js:4) with : [ null, 'aaa\nbbb\nccc\nxxx\nyyy\nzzz\n' ]
FLOWLESS: END runSeq at (/tmp/ex.js:4)
aaa
bbb
ccc
xxx
yyy
zzz
all done
var flowless = require('flowless');
Returns an asynchronous style function which runs functions in sequential.
functions
: An array of functions.
Each function can be an array as a Function Template that is
explained below.functions
in sequential.Returned function is:
function([args...,] cb)
args
: Zero or more arguments that will be passed to first element
of functions
.cb
: A callback function.If some function in the sequential throws an exception or passes an error
to its callback, no more functions are invoked and cb
is immediately
called with the exception or error.
Runs functions in sequential immediately.
functions
: An array of functions.
Each function can be an array as a Function Template that is
explained below.cb
: A callback function.Example:
flowless.runSeq([
function(cb) {
...
},
function(cb) {
...
}
], function(err, result) {
...
});
is equivalent of:
var fn = flowless.seq([
function(cb) {
...
},
function(cb) {
...
}
]);
fn(function(err, result) {
...
});
Returns an asynchronous style function which runs functions in parallel.
If any of the functions throw an exception or pass an error to its callback, the main callback is immediately called with the value of the error.
functions
: An array of functions.
Each function can be an array as a Function Template that is
explained below.functions
in parallel.Returned function is:
function([args...,] cb)
args
: Zero or more arguments that will be passed to all element
of functions
.cb
: A callback function.If any functions in the parallel throw an exception or pass an error
to its callback, cb
is immediately called with the exception or error.
Runs functions in parallel immediateley.
functions
: An array of functions.
Each function can be an array as a Function Template that is
explained below.cb
: A callback function.Example:
flowless.runPar([
function(cb) {
...
},
function(cb) {
...
}
], function(err, result) {
...
});
is equivalent of:
var fn = flowless.par([
function(cb) {
...
},
function(cb) {
...
}
]);
fn(function(err, result) {
...
});
Returns an asynchronous style function which produces a new array of values by mapping each value in the given array through the returned function.
concurrency
: A number of how many functions should be run in parallel.
Defaults to 10
.fn
: An asynchronous function which takes an element of the array
as a first argument.
It can be an array as a Function Template that is explained below.array
through fn
.fn
should be one of:
function(element, cb)
function(element, index, cb)
function(element, index, array, cb)
element
: An element of array
passed to returned function.index
: An index number of the element.array
: An array passed to returned function.cb
: A callback function.Returned function is:
function(array, cb)
array
: An array of values.cb
: A callback function.If any functions in the parallel throw an exception or pass an error
to its callback, cb
is immediately called with the exception or error.
Produces a new array of values by mapping each value in the given array through the returned function.
concurrency
: A number of how many functions should be run in parallel.
Defaults to 10
.array
: an array of values.fn
: An asynchronous function.
It can be an array as a Function Template that is explained below.cb
: A callback function.fn
should be one of:
function(element, cb)
function(element, index, cb)
function(element, index, array, cb)
element
: an element of array
.index
: An index number of the element.array
: array
passed to runMap()
.cb
: A callback function.Example:
flowless.runMap(array, function(value, cb) {
...
}, function(err, result) {
...
});
is equivalent of:
var fn = flowless.map(function(value, cb) {
...
});
fn(array, function(err, result) {
...
});
A Function template is an array representing a function and its argument.
The first or second element must be a function.
If the first element is not a function,
it will be used as a context (this
) object.
The rest of elements will be used as the arguments of the function.
The array can include a special value,
flowless.first
, flowless.second
and flowless.third
.
When the function is called,
they will be replaced with the actual argument of a corresponding position.
Example:
flowless.seq([
...
['fs.readFile', flowless.first, 'utf8'],
...
]);
is equivalent of:
flowless.seq([
...
function(file, cb) {
fs.readFile(file, 'utf8', cb);
},
...
]);
var extras = require('flowless').extras;
Provides asynchronous style functions to wrap a method of Array
.
It takes the first argument as this
.
Example:
flowless.seq([
...
extras.array.join(':'),
...
]);
is equivalent of:
flowless.seq([
...
function(self, cb) {
cb(null, self.join(':'));
},
...
]);
Provides asynchronous style functions to wrap a method of String
.
It takes the first argument as this
.
Example:
flowless.seq([
...
extras.string.split(':'),
...
]);
is equivalent of:
flowless.seq([
...
function(self, cb) {
cb(null, self.split(':'));
},
...
]);
Returns a new asynchronous style function which passes a given arguments to a callback.
args
: Values to be given in a callback.args
to a callback.Example:
flowless.seq([
extras.generate(1, 2, 3),
...
]);
is equivalent of:
flowless.seq([
function(cb) {
cb(null, 1, 2, 3);
},
...
]);
Returns a new asynchronous style function which binds an argument of the specific position (first, second or third) to a property of a target object.
target
: An object that a value is bound.name
: A string of property name that a value is bound.target
object.Example:
var context = {};
flowless.seq([
...
extras.bindFirst(context, 'name'),
...
]);
is equivalent of:
var context = {};
flowless.seq([
...
function(name, cb) {
context['name'] = name;
cb(null, name);
},
...
]);
Returns a new asynchronous style function which flatten an argument of the specific position (first, second or third).
Example:
var context = {};
flowless.seq([
extras.generate(['foo', 'bar', 'baz']),
extras.flattenFirst(),
function(foo, bar, baz, cb) { // foo: 'foo', bar: 'bar', baz: 'baz'
...
}
]);
Returns a new asynchronous style function which invokes a synchronous function and passes the return value to a callback.
fn
: A synchronous function.Example:
flowless.seq([
...
extras.makeAsync(encodeURI),
...
]);
is equivalent of:
flowless.seq([
...
function(uri, cb) {
cb(encodeURI(uri));
}),
...
]);
flowless is inspired by Slide.
flowless is licensed under the MIT license.
FAQs
Less but better control-flow library
The npm package flowless receives a total of 2 weekly downloads. As such, flowless popularity was classified as not popular.
We found that flowless demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.