genasync
v1.3.0
Published
Use async operations with generators
Downloads
5
Readme
The "genasync" package allows to deal with asynchronous functions and with
generators and curried-callbacks. This program is in the public domain.
The exported properties are:
Generator: A function for monadic generator operations. Calling this
function is an error, but it has some properties, and the prototype
property of Generator is the prototype for all generator objects.
Generator.from(x): Returns a generator from object x (anything that can
be used with "yield*").
Generator.prototype.bindG(f): Makes a new generator where each "yield x"
is replaced by "yield*f(x)".
Generator.prototype.bindR(f): Makes a new generator where each "return x"
is replaced by "return yield*f(x)".
Generator.prototype.complete(): Executes all remaining steps of the
generator, ignoring all yielded values, and causing a "yield" expression
to return undefined, and returns the final value returned with "return".
Generator.prototype.joinG(): Makes a new generator where each "yield x" is
replaced by "yield*x".
Generator.prototype.joinR(): Makes a new generator where each "return x"
is replaced by "return yield*x".
Generator.prototype.mapG(f): Makes a new generator where each "yield x" is
replaced by "yield f(x)".
Generator.prototype.mapN(f): Makes a new generator where each "yield x" is
replaced by "f(yield x)".
Generator.prototype.mapR(f): Makes a new generator where each "return x"
is replaced by "return f(x)".
Generator.prototype.return(x): It won't define this method if it already
exists. It is supposed to already exist but the current version of Node.js
does not implement it. This implementation works similarly but causes an
object to be thrown into the generator function (although most programs
would just rethrow it since it is not a recognized error).
Generator.unitG(x): Returns a generator which yields x and then returns
the result of the yield. This function is the identity for bindG.
Generator.unitR(x): Returns a generator which just returns x without ever
yielding anything. This function is the identity for bindR.
Readable(r): Call it as a constructor (with "new") to create a new object.
The argument r is a readable stream object, and it creates a new one with
two methods. You should then not attempt to read from or attach events to
the underlying stream directly, although other properties could still be
used in case there are extra ones.
Readable.prototype.read(n)(cb): Call the underlying read method and waits
for the data to be available (which may be immediately) or the stream to
end. If there is an error called e, cb(e) is called. If data is available,
cb(null,x) is called where x is data. If no data is available (due to end
of file), it will call cb(null,null).
Readable.prototype.setEncoding(x): A convenience function; calls the
underlying setEncoding method.
all(x)(cb): Calls all of the elements of array x with a callback function.
If any of these callbacks are called with a true-like first argument then
cb is also called and the rest are ignored. Otherwise it will call cb with
null and the array of results once all of the callbacks have been called.
async(f)(cb): Calls f with a function as its argument; this function will
then remember being called. It then immediately calls cb(null,x) even if
the function passed to f hasn't been called yet; x is a function that, if
called with a function as a parameter, will call that function as soon as
the function passed to f is called (immediately if it has already been).
curried(f,p): Curries out argument number (p); same as curriedER. The
number (p) is also the number of arguments expected with the resulting
function, when then returns a new function that takes one argument, and
then when that function is called, f is called with all of the arguments
put together.
curriedER(f,p): Returns a variant of function f in "curried-callbacks"
format, where the callback expects (error,result).
curriedEX(f,p): Returns a variant of function f in "curried-callbacks"
format, where the callback expects multiple arguments, the first of
which is the error. The rest are converted into an array.
curriedR(f,p): Returns a variant of function f in "curried-callbacks"
format, where the callback expects (result). The error is always null.
curriedX(f,p): Returns a variant of function f in "curried-callbacks"
format, where the callback expects any number of arguments. The list of
arguments is passed as an array.
defineER(obj,m,n,p): Where obj is an object (normally a prototype object,
although it doesn't have to be), m is the property name of an existing
method, n is the name of the new method, and p is a parameter index, it
adds that property to the object by applying curriedER to the old one.
defineEX(obj,m,n,p): Where obj is an object (normally a prototype object,
although it doesn't have to be), m is the property name of an existing
method, n is the name of the new method, and p is a parameter index, it
adds that property to the object by applying curriedEX to the old one.
defineP(obj,m,n): Where obj is an object (normally a prototype object,
although it doesn't have to be), m is the property name of an existing
method, n is the name of the new method, it adds that property to the
object by applying fromPromiseFunc to the old one.
defineR(obj,m,n,p): Where obj is an object (normally a prototype object,
although it doesn't have to be), m is the property name of an existing
method, n is the name of the new method, and p is a parameter index, it
adds that property to the object by applying curriedR to the old one.
defineX(obj,m,n,p): Where obj is an object (normally a prototype object,
although it doesn't have to be), m is the property name of an existing
method, n is the name of the new method, and p is a parameter index, it
adds that property to the object by applying curriedX to the old one.
delay(x)(cb): After x milliseconds, calls cb().
eventQueue(f): Calls the function f with two arguments. The first is a
function that when called, places its argument into a queue. The second is
the same as the return value of eventQueue, which is itself a function,
that when called, calls its argument with null and the next event that
has been dequeued; if there is no next event it waits until there is one
and then calls it immediately. The function returned by eventQueue also
has its own properties, all of which are functions: pending() returns true
if any events are pending. waiting() returns true if anything is waiting
for an event. append(x) appends an event, same as the first argument to f.
clear() will remove all events from the queue. stop() will prevent anyone
currently waiting for an event from receiving it. It is allowed to omit
the "f" function and call eventQueue with no arguments. Also note that the
methods of the returned function are automatically bound to the correct
environment and do not need a "this" parameter.
fromPromise(p)(cb): Convert a promise into curried-callbacks format.
fromPromiseFunc(f): Returns a new function that takes the same arguments
as f, but while f should return a promise, the new function instead is a
curried-callbacks format function, which won't do until the callback is
specified.
immediate(x)(cb): Calls cb(null,x).
race(x)(cb): Calls all of the elements of array x with a callback
function. Once any one of them is called, then cb is called; the others
are then ignored.
run(g): Expects g to be either a generator, or a generator function that
takes no arguments. It runs the generator until it yields or returns. If
it yields, the value it yields is expected to be a function. That function
will be called with its argument being a function that takes exactly two
arguments. If that function is called with the first argument being false
like, then the generator continues with the yield expression resulting in
the second argument; if the first argument is true like, then it is thrown
into the generator and the second argument is ignored. The callback
function does not have to be called immediately; if it is never called,
the generator never continues.
runCB(g)(cb): Similar to run but if the generator throws then cb is called
with the thrown value, and if the generator returns then cb is called with
null as the first argument and the returned value as the second argument.
It won't do anything until the cb argument is given.
runEx(g): Similar to run but returns an object which is an event emitter.
If the generator throws, the "error" event is emitted. If the generator
returns, the "done" event is emitted. It also has properties "running" and
"finished" which are boolean, and methods. The "pause" method will cause
it to pause; if the callback is called, it won't continue right away but
will remember it. The "resume" method removes the pause state, and if the
callback has been called in that time, resumes the generator. The "stop"
method will emit the "stopped" event the next time the callback is called
and will not continue; in this case the "return" method of the generator
will be called.
toPromise(f): Calls a function in curried-callbacks format and converts it
into a promise. If the callback is called with true-like first argument,
then the promise is rejected, otherwise it is successful.
waitEvent(obj,ev)(cb): Registers the one-time event handler on (obj) for
event (ev). If the event is called with argument (x), it calls cb(null,x).
Notes:
* You can call run with a generator or generator function, in order to
more easily to make asynchronous operations. It is expected to yield
functions in a "curried-callbacks" format; many of the functions described
above are like that.
* The "curried-callbacks" format means the function returns a function and
does not do anything until the returned function is called with a single
argument, which must be the callback function. Once the operation is
completed that callback function is called, which expects (error,result).
* This means that the value of "yield genasync.immediate(x)" is x (with no
side effects).
* The process.nextTick function is already in "curried-callbacks" format.
Therefore, you can "yield process.nextTick". However, if you want to allow
additional I/O to be performed then you may do "yield genasync.delay(0)"
instead.
* The "race" and "all" functions are like those for promises but these
ones act on and return curried-callbacks instead. Therefore you can yield
them from the generator passed to "run". Like other curried-callbacks
functions, they won't execute until the returned function is called.
Example:
const G=require("genasync");
const fs=require("fs");
G.defineER(fs,"readFile","readFileG",2);
A generator function called by G.run might then include something like:
buf=new Uint8Array(yield fs.readFileG(n,{}));