프로젝트

일반

사용자정보

통계
| 개정판:

root / HServer / 00.Server / 00.Program / node_modules / node.flow / Readme.md

이력 | 보기 | 이력해설 | 다운로드 (9.19 KB)

1
# node.flow
2

    
3
A deadly simple flow control package for node.js
4

    
5

    
6

    
7
## Description
8

    
9
The asynchronous nature of javascript is what makes it so powerful. However sometimes you just need to do stuffs synchronously without blocking the event loop. Stuffs like query database in a loop with ids to assemble a hash, compressing a bunch of files in groups and compare with the old ones. You could easily end up with nested callbacks without using a flow control package.
10

    
11
With node.flow you can set a work flow doing things one by one or in parallel, wait for all things are done in the parallel tasks to do the next task. You can set some default arguments for all tasks, giving each task its own arguments or pass task results to the next task as its arguments. The following code shows some base usage and the syntax of this package.
12

    
13
    // setup db schema and connection
14
    require( './setup' );
15

    
16
    var Flow     = require( '../../lib/flow' );
17
    var mongoose = require( 'mongoose' );
18
    var User     = mongoose.model( 'User' );
19
    var data     = require( './data' );
20

    
21
    // start a new flow
22
    var flow  = new Flow;
23
    var users = {};
24

    
25
    // delete all users before start
26
    flow.series( function ( next ){
27
      User.remove( function ( err, count ){
28
        next();
29
      });
30
    });
31

    
32
    // insert records from source data
33
    data.users.forEach( function ( user ){
34
      flow.parallel( function ( user, ready ){
35
        new User( user ).save( function ( err, user ){
36
          ready();
37
        });
38
      }, user );
39
    });
40

    
41
    // we must set an end point for parallel tasks
42
    flow.join();
43

    
44
    // find matching records
45
    data.names.forEach( function ( name ){
46
      flow.parallel( function( name, ready ){
47
        User.findOne({
48
          name : name
49
        }, function ( err, user ){
50
          users[ name ] = user;
51
          ready();
52
        });
53
      }, name );
54
    });
55

    
56
    flow.join();
57

    
58
    // print out records and disconnect
59
    flow.end( function(){
60
      console.log( users );
61
      mongoose.disconnect();
62
    });
63

    
64

    
65

    
66
## Requires
67

    
68
Checkout `package.json` for dependencies.
69

    
70

    
71

    
72
## Installation
73

    
74
Install node.flow through npm
75

    
76
    npm install node.flow
77

    
78

    
79

    
80
## Usage
81

    
82
> Require the module before using
83

    
84
    var Flow = require( 'node.flow' );
85

    
86

    
87

    
88
### new Flow( arg1, arg2, ... );
89

    
90
Start a new flow.
91

    
92
#### Arguments
93

    
94
> arg1, arg2, ...
95

    
96
    type: Function | String | Array | Object | Boolean
97
    desc: arguments to be passed to the new flow as defaults.
98

    
99
#### Example code
100

    
101
    var flow = new Flow( 'bibi', 22, true );
102

    
103

    
104

    
105
### flow.series( task, arg1, arg2, ... );
106

    
107
Add series task to the flow stack.
108

    
109
#### Arguments
110

    
111
> task
112

    
113
    type: Function
114
    desc: Task function to be called in series.
115

    
116
> arg1, arg2, ...
117

    
118
    type: Function | String | Array | Object | Boolean
119
    desc: Arguments to be passed to the task function( optional ).
120

    
121
#### Example code
122

    
123
    var Flow = require( 'node.flow' );
124
    var flow = new Flow();
125

    
126
    // Add a task function, the last argument in the task callback
127
    // is always the next task
128
    flow.series( function( name, sort, next ){
129
      User.find({
130
        name : name
131
      }).sort( sort, -1 ).run( function ( err, users ){
132
        // call the next series task
133
        next( users );
134
      });
135

    
136
    // 'bibi' will be passed to the task function as the first argument `name`
137
    // and 'created_at' will be the second argument `sort`
138
    // you can series as many arguments as you want
139
    }, 'bibi', 'created_at' );
140

    
141

    
142

    
143
### flow.parallel( task, arg1, arg2, ... );
144

    
145
Add parallel task to the flow stack.
146

    
147
#### Arguments
148

    
149
> callback
150

    
151
    type: Function
152
    desc: Task function to be called in parallel.
153

    
154
> arg1, arg2, ...
155

    
156
    type: Function | String | Array | Object | Boolean
157
    desc: Arguments to be passed to the task function( optional ).
158

    
159
#### Example code
160

    
161
    var Flow = require( 'node.flow' );
162
    var flow = new Flow();
163

    
164
    flow.parallel( function( name, sort, ready ){
165
      User.find({
166
        name : name
167
      }).sort( sort, -1 ).run( function ( err, users ){
168
        ready( users );
169
      });
170
    }, 'bibi', 'created_at' );
171

    
172

    
173

    
174
### flow.join();
175

    
176
Set an end point for a group of parallel tasks.
177

    
178
#### Example code
179

    
180
    var Flow = require( 'node.flow' );
181
    var flow = new Flow();
182

    
183
    flow.parallel( function( name, sort, ready ){
184
      User.find({
185
        name : name
186
      }).sort( sort, -1 ).run( function ( err, users ){
187
        ready( users );
188
      });
189
    }, 'bibi', 'created_at' );
190

    
191
    flow.join();
192

    
193

    
194

    
195
### flow.error( callback );
196

    
197
Error handler for in case there is any.
198

    
199
#### Arguments
200

    
201
> callback
202

    
203
    type: Function
204
    desc: Error handler to break the flow.
205

    
206
#### Example code
207

    
208
    var Flow = require( 'node.flow' );
209
    var flow = new Flow();
210

    
211
    flow.error( function ( err ){
212
      console.log( err );
213
    });
214

    
215

    
216

    
217
### flow.end( callback, arg1, arg2, ... );
218

    
219
Call the tasks one after another in the stack.
220

    
221
#### Arguments
222

    
223
> callback
224

    
225
    type: Function
226
    desc: The last callback to be called at the very end after all tasks are done
227

    
228
> arg1, arg2, ...
229

    
230
    type: Function | String | Array | Object | Boolean
231
    desc: Arguments to be passed to the callback function( optional )
232

    
233
#### Example code
234

    
235
    var Flow = require( 'node.flow' );
236
    var flow = new Flow();
237
    var users = {};
238

    
239
    // find users with the given names
240
    [ 'fifi', 'jenny', 'steffi' ].forEach( function ( name ){
241
      // assign 3 parallel tasks searching for users
242
      flow.parallel( function( users, name, ready ){
243
        User.findOne({
244
          name : name
245
        }, function ( err, user ){
246
          users[ name ] = user;
247
          ready();
248
        });
249
      }, users, name )
250
    });
251

    
252
    flow.join();
253

    
254
    // print out the search results
255
    flow.end( function( users ){
256
      console.log( users );
257
    });
258

    
259

    
260

    
261
## Arguments merge and overwrite
262

    
263
You can set some default arguments for all tasks, giving each task its own arguments or pass task results to the next task as its arguments. The priority is `argements from last task` > `argements for each task` > `default argements`. Which means `default argements` will be merge into `argements for each task` and finally merge into `argements from last task` than pass to the next task. However with parallel tasks it works a little different. Results from parallel tasks will be push to a stack, when all parallel tasks are done the result stack will be the first argument assign to `argements for each task` unless the result stack is empty. Checkout the parallel example for a clear view.
264

    
265

    
266

    
267
## Chainability
268

    
269
You can either choose to chain your methods or not up to your personal taste. Both of the following syntax works.
270

    
271
    // chaining all methods
272
    flow.series( function (){
273
      // do stuffs ...
274
    }).parallel( function (){
275
      // do stuffs ...
276
    }).parallel( function (){
277
      // do stuffs ...
278
    }).join().
279
    series( function (){
280
      // do stuffs ...
281
    end( function (){
282
      // all done callback
283
    });
284

    
285
    // seperate all methods
286
    flow.series( function (){
287
      // do stuffs ...
288
    });
289

    
290
    flow.parallel( function (){
291
      // do stuffs ...
292
    });
293

    
294
    flow.parallel( function (){
295
      // do stuffs ...
296
    });
297

    
298
    flow.join();
299

    
300
    flow.series( function (){
301
      // do stuffs ...
302
    });
303

    
304
    flow.end( function (){
305
      // all done callback
306
    });
307

    
308
## Examples
309

    
310
> Checkout the `examples` folder for more details.
311

    
312
### series
313

    
314
> Demonstrate the basic usage of series task and syntax. We use setTimeout to simulate a time consuming io operation. We can see how the arguments are merged and overwrote in the example.
315

    
316
    $ cd /path/to/node.flow/examples/series
317
    $ node run.js
318

    
319
### parallel
320

    
321
> Demonstrate the basic usage of parallel task and syntax.
322

    
323
    $ cd /path/to/node.flow/examples/parallel
324
    $ node run.js
325

    
326
### mongoose
327

    
328
> Demonstrate how to clear the documents before inserting a bunch of records then finding some records with given conditions in a loop and show them without writing nested callbacks. Use both series and parallel tasks.
329

    
330
    # make sure your mongoDB is on
331
    $ cd /path/to/node.flow/examples/mongoose
332
    $ npm install -lf
333
    $ node run.js
334

    
335
### node.packer
336

    
337
> Demonstrate how to compress a bunch of files in groups.
338

    
339
    $ cd /path/to/node.flow/examples/node.packer
340
    $ npm install -lf
341
    $ node app.js
342

    
343

    
344

    
345
## License
346

    
347
(The MIT License)
348

    
349
Copyright (c) 2011 dreamerslab <ben@dreamerslab.com>
350

    
351
Permission is hereby granted, free of charge, to any person obtaining
352
a copy of this software and associated documentation files (the
353
'Software'), to deal in the Software without restriction, including
354
without limitation the rights to use, copy, modify, merge, publish,
355
distribute, sublicense, and/or sell copies of the Software, and to
356
permit persons to whom the Software is furnished to do so, subject to
357
the following conditions:
358

    
359
The above copyright notice and this permission notice shall be
360
included in all copies or substantial portions of the Software.
361

    
362
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
363
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
364
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
365
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
366
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
367
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
368
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.