Initial import from local backup (Documents-Playground/pakerpale)
This commit is contained in:
442
node_modules/seq/README.markdown
generated
vendored
Normal file
442
node_modules/seq/README.markdown
generated
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
Seq
|
||||
===
|
||||
|
||||
Seq is an asynchronous flow control library with a chainable interface for
|
||||
sequential and parallel actions. Even the error handling is chainable.
|
||||
|
||||
Each action in the chain operates on a stack of values.
|
||||
There is also a variables hash for storing values by name.
|
||||
|
||||
[TOC]
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
stat_all.js
|
||||
-----------
|
||||
|
||||
````javascript
|
||||
var fs = require('fs');
|
||||
var Hash = require('hashish');
|
||||
var Seq = require('seq');
|
||||
|
||||
Seq()
|
||||
.seq(function () {
|
||||
fs.readdir(__dirname, this);
|
||||
})
|
||||
.flatten()
|
||||
.parEach(function (file) {
|
||||
fs.stat(__dirname + '/' + file, this.into(file));
|
||||
})
|
||||
.seq(function () {
|
||||
var sizes = Hash.map(this.vars, function (s) { return s.size })
|
||||
console.dir(sizes);
|
||||
})
|
||||
;
|
||||
````
|
||||
|
||||
Output:
|
||||
|
||||
{ 'stat_all.js': 404, 'parseq.js': 464 }
|
||||
|
||||
parseq.js
|
||||
---------
|
||||
|
||||
````javascript
|
||||
var fs = require('fs');
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
var Seq = require('seq');
|
||||
Seq()
|
||||
.seq(function () {
|
||||
exec('whoami', this)
|
||||
})
|
||||
.par(function (who) {
|
||||
exec('groups ' + who, this);
|
||||
})
|
||||
.par(function (who) {
|
||||
fs.readFile(__filename, 'ascii', this);
|
||||
})
|
||||
.seq(function (groups, src) {
|
||||
console.log('Groups: ' + groups.trim());
|
||||
console.log('This file has ' + src.length + ' bytes');
|
||||
})
|
||||
;
|
||||
````
|
||||
|
||||
Output:
|
||||
|
||||
Groups: substack : substack dialout cdrom floppy audio src video plugdev games netdev fuse www
|
||||
This file has 464 bytes
|
||||
|
||||
|
||||
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
Each method executes callbacks with a context (its `this`) described in the next
|
||||
section. Every method returns `this`.
|
||||
|
||||
Whenever `this()` is called with a non-falsy first argument, the error value
|
||||
propagates down to the first `catch` it sees, skipping over all actions in
|
||||
between. There is an implicit `catch` at the end of all chains that prints the
|
||||
error stack if available and otherwise just prints the error.
|
||||
|
||||
|
||||
|
||||
Seq(xs=[])
|
||||
----------
|
||||
|
||||
The constructor function creates a new `Seq` chain with the methods described
|
||||
below. The optional array argument becomes the new context stack.
|
||||
|
||||
Array argument is new in 0.3. `Seq()` now behaves like `Seq.ap()`.
|
||||
|
||||
|
||||
.seq(cb)
|
||||
--------
|
||||
.seq(key, cb, *args)
|
||||
--------------------
|
||||
|
||||
This eponymous function executes actions sequentially.
|
||||
Once all running parallel actions are finished executing,
|
||||
the supplied callback is `apply()`'d with the context stack.
|
||||
|
||||
To execute the next action in the chain, call `this()`. The first
|
||||
argument must be the error value. The rest of the values will become the stack
|
||||
for the next action in the chain and are also available at `this.args`.
|
||||
|
||||
If `key` is specified, the second argument sent to `this` goes to
|
||||
`this.vars[key]` in addition to the stack and `this.args`.
|
||||
`this.vars` persists across all requests unless it is overwritten.
|
||||
|
||||
All arguments after `cb` will be bound to `cb`, which is useful because
|
||||
`.bind()` makes you set `this`. If you pass in `Seq` in the arguments list,
|
||||
it'll get transformed into `this` so that you can do:
|
||||
|
||||
````javascript
|
||||
Seq()
|
||||
.seq(fs.readdir, __dirname, Seq)
|
||||
.seq(function (files) { console.dir(files) })
|
||||
;
|
||||
````
|
||||
|
||||
which prints an array of files in `__dirname`.
|
||||
|
||||
|
||||
.par(cb)
|
||||
--------
|
||||
.par(key, cb, *args)
|
||||
--------------------
|
||||
|
||||
Use `par` to execute actions in parallel.
|
||||
Chain multiple parallel actions together and collect all the responses on the
|
||||
stack with a sequential operation like `seq`.
|
||||
|
||||
Each `par` sets one element in the stack with the second argument to `this()` in
|
||||
the order in which it appears, so multiple `par`s can be chained together.
|
||||
|
||||
Like with `seq`, the first argument to `this()` should be the error value and
|
||||
the second will get pushed to the stack. Further arguments are available in
|
||||
`this.args`.
|
||||
|
||||
If `key` is specified, the result from the second argument send to `this()` goes
|
||||
to `this.vars[key]`.
|
||||
`this.vars` persists across all requests unless it is overwritten.
|
||||
|
||||
All arguments after `cb` will be bound to `cb`, which is useful because
|
||||
`.bind()` makes you set `this`. Like `.seq()`, you can pass along `Seq` in these
|
||||
bound arguments and it will get tranformed into `this`.
|
||||
|
||||
|
||||
.catch(cb)
|
||||
----------
|
||||
|
||||
Catch errors. Whenever a function calls `this` with a non-falsy first argument,
|
||||
the message propagates down the chain to the first `catch` it sees.
|
||||
The callback `cb` fires with the error object as its first argument and the key
|
||||
that the action that caused the error was populating, which may be undefined.
|
||||
|
||||
`catch` is a sequential action and further actions may appear after a `catch` in
|
||||
a chain. If the execution reaches a `catch` in a chain and no error has occured,
|
||||
the `catch` is skipped over.
|
||||
|
||||
For convenience, there is a default error handler at the end of all chains.
|
||||
This default error handler looks like this:
|
||||
|
||||
````javascript
|
||||
.catch(function (err) {
|
||||
console.error(err.stack ? err.stack : err)
|
||||
})
|
||||
````
|
||||
|
||||
|
||||
.forEach(cb)
|
||||
------------
|
||||
|
||||
Execute each action in the stack under the context of the chain object.
|
||||
`forEach` does not wait for any of the actions to finish and does not itself
|
||||
alter the stack, but the callback may alter the stack itself by modifying
|
||||
`this.stack`.
|
||||
|
||||
The callback is executed `cb(x,i)` where `x` is the element and `i` is the
|
||||
index.
|
||||
|
||||
`forEach` is a sequential operation like `seq` and won't run until all pending
|
||||
parallel requests yield results.
|
||||
|
||||
|
||||
.seqEach(cb)
|
||||
------------
|
||||
|
||||
Like `forEach`, call `cb` for each element on the stack, but unlike `forEach`,
|
||||
`seqEach` waits for the callback to yield with `this` before moving on to the
|
||||
next element in the stack.
|
||||
|
||||
The callback is executed `cb(x,i)` where `x` is the element and `i` is the
|
||||
index.
|
||||
|
||||
If `this()` is supplied non-falsy error, the error propagates downward but any
|
||||
other arguments are ignored. `seqEach` does not modify the stack itself.
|
||||
|
||||
|
||||
.parEach(cb)
|
||||
------------
|
||||
.parEach(limit, cb)
|
||||
-------------------
|
||||
|
||||
Like `forEach`, calls cb for each element in the stack and doesn't wait for the
|
||||
callback to yield a result with `this()` before moving on to the next iteration.
|
||||
Unlike `forEach`, `parEach` waits for all actions to call `this()` before moving
|
||||
along to the next action in the chain.
|
||||
|
||||
The callback is executed `cb(x,i)` where `x` is the element and `i` is the
|
||||
index.
|
||||
|
||||
`parEach` does not modify the stack itself and errors supplied to `this()`
|
||||
propagate.
|
||||
|
||||
Optionally, if limit is supplied to `parEach`, at most `limit` callbacks will be
|
||||
active at a time.
|
||||
|
||||
|
||||
.seqMap(cb)
|
||||
-----------
|
||||
|
||||
Like `seqEach`, but collect the values supplied to `this` and set the stack to
|
||||
these values.
|
||||
|
||||
|
||||
.parMap(cb)
|
||||
-----------
|
||||
.parMap(limit, cb)
|
||||
------------------
|
||||
|
||||
Like `parEach`, but collect the values supplied to `this` and set the stack to
|
||||
these values.
|
||||
|
||||
|
||||
.seqFilter(cb)
|
||||
-----------
|
||||
|
||||
Executes the callback `cb(x, idx)` against each element on the stack, waiting for the
|
||||
callback to yield with `this` before moving on to the next element. If the callback
|
||||
returns an error or a falsey value, the element will not be included in the resulting
|
||||
stack.
|
||||
|
||||
Any errors from the callback are consumed and **do not** propagate.
|
||||
|
||||
Calls to `this.into(i)` will place the value, if accepted by the callback, at the index in
|
||||
the results as if it were ordered at i-th index on the stack before filtering (with ties
|
||||
broken by the values). This implies `this.into` will never override another stack value
|
||||
even if their indices collide. Finally, the value will only actually appear at `i` if the
|
||||
callback accepts or moves enough values before `i`.
|
||||
|
||||
|
||||
.parFilter(cb)
|
||||
-----------
|
||||
.parFilter(limit, cb)
|
||||
------------------
|
||||
|
||||
Executes the callback `cb(x, idx)` against each element on the stack, but **does not**
|
||||
wait for it to yield before moving on to the next element. If the callback returns an
|
||||
error or a falsey value, the element will not be included in the resulting stack.
|
||||
|
||||
Any errors from the callback are consumed and **do not** propagate.
|
||||
|
||||
Calls to `this.into(i)` will place the value, if accepted by the callback, at the index in
|
||||
the results as if it were ordered at i-th index on the stack before filtering (with ties
|
||||
broken by the values). This implies `this.into` will never override another stack value
|
||||
even if their indices collide. Finally, the value will only actually appear at `i` if the
|
||||
callback accepts or moves enough values before `i`.
|
||||
|
||||
Optionally, if limit is supplied to `parEach`, at most `limit` callbacks will be
|
||||
active at a time.
|
||||
|
||||
|
||||
.do(cb)
|
||||
-------
|
||||
Create a new nested context. `cb`'s first argument is the previous context, and `this`
|
||||
is the nested `Seq` object.
|
||||
|
||||
|
||||
.flatten(fully=true)
|
||||
--------------------
|
||||
|
||||
Recursively flatten all the arrays in the stack. Set `fully=false` to flatten
|
||||
only one level.
|
||||
|
||||
|
||||
.unflatten()
|
||||
------------
|
||||
|
||||
Turn the contents of the stack into a single array item. You can think of it
|
||||
as the inverse of `flatten(false)`.
|
||||
|
||||
|
||||
.extend([x,y...])
|
||||
-----------------
|
||||
|
||||
Like `push`, but takes an array. This is like python's `[].extend()`.
|
||||
|
||||
|
||||
.set(xs)
|
||||
--------
|
||||
|
||||
Set the stack to a new array. This assigns the reference, it does not copy.
|
||||
|
||||
|
||||
.empty()
|
||||
--------
|
||||
|
||||
Set the stack to [].
|
||||
|
||||
|
||||
.push(x,y...), .pop(), .shift(), .unshift(x), .splice(...), reverse()
|
||||
---------------------------------------------------------------------
|
||||
.map(...), .filter(...), .reduce(...)
|
||||
-------------------------------------
|
||||
|
||||
Executes an array operation on the stack.
|
||||
|
||||
The methods `map`, `filter`, and `reduce` are also proxies to their Array counterparts:
|
||||
they have identical signatures to the Array methods, operate synchronously on the context
|
||||
stack, and do not pass a Context object (unlike `seqMap` and `parMap`).
|
||||
|
||||
The result of the transformation is assigned to the context stack; in the case of `reduce`,
|
||||
if you do not return an array, the value will be wrapped in one.
|
||||
|
||||
````javascript
|
||||
Seq([1, 2, 3])
|
||||
.reduce(function(sum, x){ return sum + x; }, 0)
|
||||
.seq(function(sum){
|
||||
console.log('sum: %s', sum);
|
||||
// sum: 6
|
||||
console.log('stack is Array?', Array.isArray(this.stack));
|
||||
// stack is Array: true
|
||||
console.log('stack:', this.stack);
|
||||
// stack: [6]
|
||||
})
|
||||
;
|
||||
````
|
||||
|
||||
|
||||
|
||||
|
||||
Explicit Parameters
|
||||
-------------------
|
||||
|
||||
For environments like coffee-script or nested logic where threading `this` is
|
||||
bothersome, you can use:
|
||||
|
||||
* seq_
|
||||
* par_
|
||||
* forEach_
|
||||
* seqEach_
|
||||
* parEach_
|
||||
* seqMap_
|
||||
* parMap_
|
||||
|
||||
which work exactly like their un-underscored counterparts except for the first
|
||||
parameter to the supplied callback is set to the context, `this`.
|
||||
|
||||
|
||||
|
||||
Context Object
|
||||
==============
|
||||
|
||||
Each callback gets executed with its `this` set to a function in order to yield
|
||||
results, error values, and control. The function also has these useful fields:
|
||||
|
||||
this.stack
|
||||
----------
|
||||
|
||||
The execution stack.
|
||||
|
||||
this.stack_
|
||||
-----------
|
||||
|
||||
The previous stack value, mostly used internally for hackish purposes.
|
||||
|
||||
this.vars
|
||||
---------
|
||||
|
||||
A hash of key/values populated with `par(key, ...)`, `seq(key, ...)` and
|
||||
`this.into(key)`.
|
||||
|
||||
this.into(key)
|
||||
--------------
|
||||
|
||||
Instead of sending values to the stack, sets a key and returns `this`.
|
||||
Use `this.into(key)` interchangeably with `this` for yielding keyed results.
|
||||
`into` overrides the optional key set by `par(key, ...)` and `seq(key, ...)`.
|
||||
|
||||
this.ok
|
||||
-------
|
||||
|
||||
Set the `err` to null. Equivalent to `this.bind(this, null)`.
|
||||
|
||||
this.args
|
||||
---------
|
||||
|
||||
`this.args` is like `this.stack`, but it contains all the arguments to `this()`
|
||||
past the error value, not just the first. `this.args` is an array with the same
|
||||
indices as `this.stack` but also stores keyed values for the last sequential
|
||||
operation. Each element in `this.array` is set to `[].slice.call(arguments, 1)`
|
||||
from inside `this()`.
|
||||
|
||||
this.error
|
||||
----------
|
||||
|
||||
This is used for error propagation. You probably shouldn't mess with it.
|
||||
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
With [npm](http://github.com/isaacs/npm), just do:
|
||||
|
||||
npm install seq
|
||||
|
||||
or clone this project on github:
|
||||
|
||||
git clone http://github.com/substack/node-seq.git
|
||||
|
||||
To run the tests with [expresso](http://github.com/visionmedia/expresso),
|
||||
just do:
|
||||
|
||||
expresso
|
||||
|
||||
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
This module uses [chainsaw](http://github.com/substack/node-chainsaw)
|
||||
When you `npm install seq` this dependency will automatically be installed.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user