프로젝트

일반

사용자정보

통계
| 개정판:

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

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

1 39 HKM
# 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.