Name: js-handler/node_modules/nodeunit/node_modules/tap/node_modules/slide/README.md 
1:
# Controlling Flow: callbacks are easy
2:
 
3:
## What's actually hard?
4:
 
5:
- Doing a bunch of things in a specific order.
6:
- Knowing when stuff is done.
7:
- Handling failures.
8:
- Breaking up functionality into parts (avoid nested inline callbacks)
9:
 
10:
 
11:
## Common Mistakes
12:
 
13:
- Abandoning convention and consistency.
14:
- Putting all callbacks inline.
15:
- Using libraries without grokking them.
16:
- Trying to make async code look sync.
17:
 
18:
## Define Conventions
19:
 
20:
- Two kinds of functions: *actors* take action, *callbacks* get results.
21:
- Essentially the continuation pattern. Resulting code *looks* similar
22:
  to fibers, but is *much* simpler to implement.
23:
- Node works this way in the lowlevel APIs already, and it's very flexible.
24:
 
25:
## Callbacks
26:
 
27:
- Simple responders
28:
- Must always be prepared to handle errors, that's why it's the first argument.
29:
- Often inline anonymous, but not always.
30:
- Can trap and call other callbacks with modified data, or pass errors upwards.
31:
 
32:
## Actors
33:
 
34:
- Last argument is a callback.
35:
- If any error occurs, and can't be handled, pass it to the callback and return.
36:
- Must not throw. Return value ignored.
37:
- return x ==> return cb(null, x)
38:
- throw er ==> return cb(er)
39:
 
40:
```javascript
41:
// return true if a path is either
42:
// a symlink or a directory.
43:
function isLinkOrDir (path, cb) {
44:
  fs.lstat(path, function (er, s) {
45:
    if (er) return cb(er)
46:
    return cb(null, s.isDirectory() || s.isSymbolicLink())
47:
  })
48:
}
49:
```
50:
 
51:
# asyncMap
52:
 
53:
## Usecases
54:
 
55:
- I have a list of 10 files, and need to read all of them, and then continue when they're all done.
56:
- I have a dozen URLs, and need to fetch them all, and then continue when they're all done.
57:
- I have 4 connected users, and need to send a message to all of them, and then continue when that's done.
58:
- I have a list of n things, and I need to dosomething with all of them, in parallel, and get the results once they're all complete.
59:
 
60:
 
61:
## Solution
62:
 
63:
```javascript
64:
var asyncMap = require("slide").asyncMap
65:
function writeFiles (files, what, cb) {
66:
  asyncMap(files, function (f, cb) {
67:
    fs.writeFile(f, what, cb)
68:
  }, cb)
69:
}
70:
writeFiles([my, file, list], "foo", cb)
71:
```
72:
 
73:
# chain
74:
 
75:
## Usecases
76:
 
77:
- I have to do a bunch of things, in order. Get db credentials out of a file,
78:
  read the data from the db, write that data to another file.
79:
- If anything fails, do not continue.
80:
- I still have to provide an array of functions, which is a lot of boilerplate,
81:
  and a pita if your functions take args like
82:
 
83:
```javascript
84:
function (cb) {
85:
  blah(a, b, c, cb)
86:
}
87:
```
88:
 
89:
- Results are discarded, which is a bit lame.
90:
- No way to branch.
91:
 
92:
## Solution
93:
 
94:
- reduces boilerplate by converting an array of [fn, args] to an actor
95:
  that takes no arguments (except cb)
96:
- A bit like Function#bind, but tailored for our use-case.
97:
- bindActor(obj, "method", a, b, c)
98:
- bindActor(fn, a, b, c)
99:
- bindActor(obj, fn, a, b, c)
100:
- branching, skipping over falsey arguments
101:
 
102:
```javascript
103:
chain([
104:
  doThing && [thing, a, b, c]
105:
, isFoo && [doFoo, "foo"]
106:
, subChain && [chain, [one, two]]
107:
], cb)
108:
```
109:
 
110:
- tracking results: results are stored in an optional array passed as argument,
111:
  last result is always in results[results.length - 1].
112:
- treat chain.first and chain.last as placeholders for the first/last
113:
  result up until that point.
114:
 
115:
 
116:
## Non-trivial example
117:
 
118:
- Read number files in a directory
119:
- Add the results together
120:
- Ping a web service with the result
121:
- Write the response to a file
122:
- Delete the number files
123:
 
124:
```javascript
125:
var chain = require("slide").chain
126:
function myProgram (cb) {
127:
  var res = [], last = chain.last, first = chain.first
128:
  chain([
129:
    [fs, "readdir", "the-directory"]
130:
  , [readFiles, "the-directory", last]
131:
  , [sum, last]
132:
  , [ping, "POST", "example.com", 80, "/foo", last]
133:
  , [fs, "writeFile", "result.txt", last]
134:
  , [rmFiles, "./the-directory", first]
135:
  ], res, cb)
136:
}
137:
```
138:
 
139:
# Conclusion: Convention Profits
140:
 
141:
- Consistent API from top to bottom.
142:
- Sneak in at any point to inject functionality. Testable, reusable, ...
143:
- When ruby and python users whine, you can smile condescendingly.