프로젝트

일반

사용자정보

통계
| 개정판:

root / HServer / 00.Server / 00.Program / node_modules / kareem / README.md

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

1
# kareem
2

    
3
  [![Build Status](https://travis-ci.org/vkarpov15/kareem.svg?branch=master)](https://travis-ci.org/vkarpov15/kareem)
4
  [![Coverage Status](https://img.shields.io/coveralls/vkarpov15/kareem.svg)](https://coveralls.io/r/vkarpov15/kareem)
5

    
6
Re-imagined take on the [hooks](http://npmjs.org/package/hooks) module, meant to offer additional flexibility in allowing you to execute hooks whenever necessary, as opposed to simply wrapping a single function.
7

    
8
Named for the NBA's all-time leading scorer Kareem Abdul-Jabbar, known for his mastery of the [hook shot](http://en.wikipedia.org/wiki/Kareem_Abdul-Jabbar#Skyhook)
9

    
10
<img src="http://upload.wikimedia.org/wikipedia/commons/0/00/Kareem-Abdul-Jabbar_Lipofsky.jpg" width="220">
11

    
12
# API
13

    
14
## pre hooks
15

    
16
Much like [hooks](https://npmjs.org/package/hooks), kareem lets you define
17
pre and post hooks: pre hooks are called before a given function executes.
18
Unlike hooks, kareem stores hooks and other internal state in a separate
19
object, rather than relying on inheritance. Furthermore, kareem exposes
20
an `execPre()` function that allows you to execute your pre hooks when
21
appropriate, giving you more fine-grained control over your function hooks.
22

    
23

    
24
#### It runs without any hooks specified
25

    
26
```javascript
27
    
28
    hooks.execPre('cook', null, function() {
29
      done();
30
    });
31
  
32
```
33

    
34
#### It runs basic serial pre hooks
35

    
36
pre hook functions take one parameter, a "done" function that you execute
37
when your pre hook is finished.
38

    
39

    
40
```javascript
41
    
42
    var count = 0;
43

    
44
    hooks.pre('cook', function(done) {
45
      ++count;
46
      done();
47
    });
48

    
49
    hooks.execPre('cook', null, function() {
50
      assert.equal(1, count);
51
      done();
52
    });
53
  
54
```
55

    
56
#### It can run multipe pre hooks
57

    
58
```javascript
59
    
60
    var count1 = 0;
61
    var count2 = 0;
62

    
63
    hooks.pre('cook', function(done) {
64
      ++count1;
65
      done();
66
    });
67

    
68
    hooks.pre('cook', function(done) {
69
      ++count2;
70
      done();
71
    });
72

    
73
    hooks.execPre('cook', null, function() {
74
      assert.equal(1, count1);
75
      assert.equal(1, count2);
76
      done();
77
    });
78
  
79
```
80

    
81
#### It can run fully synchronous pre hooks
82

    
83
If your pre hook function takes no parameters, its assumed to be
84
fully synchronous.
85

    
86

    
87
```javascript
88
    
89
    var count1 = 0;
90
    var count2 = 0;
91

    
92
    hooks.pre('cook', function() {
93
      ++count1;
94
    });
95

    
96
    hooks.pre('cook', function() {
97
      ++count2;
98
    });
99

    
100
    hooks.execPre('cook', null, function(error) {
101
      assert.equal(null, error);
102
      assert.equal(1, count1);
103
      assert.equal(1, count2);
104
      done();
105
    });
106
  
107
```
108

    
109
#### It properly attaches context to pre hooks
110

    
111
Pre save hook functions are bound to the second parameter to `execPre()`
112

    
113

    
114
```javascript
115
    
116
    hooks.pre('cook', function(done) {
117
      this.bacon = 3;
118
      done();
119
    });
120

    
121
    hooks.pre('cook', function(done) {
122
      this.eggs = 4;
123
      done();
124
    });
125

    
126
    var obj = { bacon: 0, eggs: 0 };
127

    
128
    // In the pre hooks, `this` will refer to `obj`
129
    hooks.execPre('cook', obj, function(error) {
130
      assert.equal(null, error);
131
      assert.equal(3, obj.bacon);
132
      assert.equal(4, obj.eggs);
133
      done();
134
    });
135
  
136
```
137

    
138
#### It can execute parallel (async) pre hooks
139

    
140
Like the hooks module, you can declare "async" pre hooks - these take two
141
parameters, the functions `next()` and `done()`. `next()` passes control to
142
the next pre hook, but the underlying function won't be called until all
143
async pre hooks have called `done()`.
144

    
145

    
146
```javascript
147
    
148
    hooks.pre('cook', true, function(next, done) {
149
      this.bacon = 3;
150
      next();
151
      setTimeout(function() {
152
        done();
153
      }, 5);
154
    });
155

    
156
    hooks.pre('cook', true, function(next, done) {
157
      next();
158
      var _this = this;
159
      setTimeout(function() {
160
        _this.eggs = 4;
161
        done();
162
      }, 10);
163
    });
164

    
165
    hooks.pre('cook', function(next) {
166
      this.waffles = false;
167
      next();
168
    });
169

    
170
    var obj = { bacon: 0, eggs: 0 };
171

    
172
    hooks.execPre('cook', obj, function() {
173
      assert.equal(3, obj.bacon);
174
      assert.equal(4, obj.eggs);
175
      assert.equal(false, obj.waffles);
176
      done();
177
    });
178
  
179
```
180

    
181
#### It supports returning a promise
182

    
183
You can also return a promise from your pre hooks instead of calling
184
`next()`. When the returned promise resolves, kareem will kick off the
185
next middleware.
186

    
187

    
188
```javascript
189
    
190
    hooks.pre('cook', function() {
191
      return new Promise(resolve => {
192
        setTimeout(() => {
193
          this.bacon = 3;
194
          resolve();
195
        }, 100);
196
      });
197
    });
198

    
199
    var obj = { bacon: 0 };
200

    
201
    hooks.execPre('cook', obj, function() {
202
      assert.equal(3, obj.bacon);
203
      done();
204
    });
205
  
206
```
207

    
208
## post hooks
209

    
210
#### It runs without any hooks specified
211

    
212
```javascript
213
    
214
    hooks.execPost('cook', null, [1], function(error, eggs) {
215
      assert.ifError(error);
216
      assert.equal(1, eggs);
217
      done();
218
    });
219
  
220
```
221

    
222
#### It executes with parameters passed in
223

    
224
```javascript
225
    
226
    hooks.post('cook', function(eggs, bacon, callback) {
227
      assert.equal(1, eggs);
228
      assert.equal(2, bacon);
229
      callback();
230
    });
231

    
232
    hooks.execPost('cook', null, [1, 2], function(error, eggs, bacon) {
233
      assert.ifError(error);
234
      assert.equal(1, eggs);
235
      assert.equal(2, bacon);
236
      done();
237
    });
238
  
239
```
240

    
241
#### It can use synchronous post hooks
242

    
243
```javascript
244
    
245
    var execed = {};
246

    
247
    hooks.post('cook', function(eggs, bacon) {
248
      execed.first = true;
249
      assert.equal(1, eggs);
250
      assert.equal(2, bacon);
251
    });
252

    
253
    hooks.post('cook', function(eggs, bacon, callback) {
254
      execed.second = true;
255
      assert.equal(1, eggs);
256
      assert.equal(2, bacon);
257
      callback();
258
    });
259

    
260
    hooks.execPost('cook', null, [1, 2], function(error, eggs, bacon) {
261
      assert.ifError(error);
262
      assert.equal(2, Object.keys(execed).length);
263
      assert.ok(execed.first);
264
      assert.ok(execed.second);
265
      assert.equal(1, eggs);
266
      assert.equal(2, bacon);
267
      done();
268
    });
269
  
270
```
271

    
272
## wrap()
273

    
274
#### It wraps pre and post calls into one call
275

    
276
```javascript
277
    
278
    hooks.pre('cook', true, function(next, done) {
279
      this.bacon = 3;
280
      next();
281
      setTimeout(function() {
282
        done();
283
      }, 5);
284
    });
285

    
286
    hooks.pre('cook', true, function(next, done) {
287
      next();
288
      var _this = this;
289
      setTimeout(function() {
290
        _this.eggs = 4;
291
        done();
292
      }, 10);
293
    });
294

    
295
    hooks.pre('cook', function(next) {
296
      this.waffles = false;
297
      next();
298
    });
299

    
300
    hooks.post('cook', function(obj) {
301
      obj.tofu = 'no';
302
    });
303

    
304
    var obj = { bacon: 0, eggs: 0 };
305

    
306
    var args = [obj];
307
    args.push(function(error, result) {
308
      assert.ifError(error);
309
      assert.equal(null, error);
310
      assert.equal(3, obj.bacon);
311
      assert.equal(4, obj.eggs);
312
      assert.equal(false, obj.waffles);
313
      assert.equal('no', obj.tofu);
314

    
315
      assert.equal(obj, result);
316
      done();
317
    });
318

    
319
    hooks.wrap(
320
      'cook',
321
      function(o, callback) {
322
        assert.equal(3, obj.bacon);
323
        assert.equal(4, obj.eggs);
324
        assert.equal(false, obj.waffles);
325
        assert.equal(undefined, obj.tofu);
326
        callback(null, o);
327
      },
328
      obj,
329
      args);
330
  
331
```
332

    
333
## createWrapper()
334

    
335
#### It wraps wrap() into a callable function
336

    
337
```javascript
338
    
339
    hooks.pre('cook', true, function(next, done) {
340
      this.bacon = 3;
341
      next();
342
      setTimeout(function() {
343
        done();
344
      }, 5);
345
    });
346

    
347
    hooks.pre('cook', true, function(next, done) {
348
      next();
349
      var _this = this;
350
      setTimeout(function() {
351
        _this.eggs = 4;
352
        done();
353
      }, 10);
354
    });
355

    
356
    hooks.pre('cook', function(next) {
357
      this.waffles = false;
358
      next();
359
    });
360

    
361
    hooks.post('cook', function(obj) {
362
      obj.tofu = 'no';
363
    });
364

    
365
    var obj = { bacon: 0, eggs: 0 };
366

    
367
    var cook = hooks.createWrapper(
368
      'cook',
369
      function(o, callback) {
370
        assert.equal(3, obj.bacon);
371
        assert.equal(4, obj.eggs);
372
        assert.equal(false, obj.waffles);
373
        assert.equal(undefined, obj.tofu);
374
        callback(null, o);
375
      },
376
      obj);
377

    
378
    cook(obj, function(error, result) {
379
      assert.ifError(error);
380
      assert.equal(3, obj.bacon);
381
      assert.equal(4, obj.eggs);
382
      assert.equal(false, obj.waffles);
383
      assert.equal('no', obj.tofu);
384

    
385
      assert.equal(obj, result);
386
      done();
387
    });
388
  
389
```
390

    
391
## clone()
392

    
393
#### It clones a Kareem object
394

    
395
```javascript
396
    
397
    var k1 = new Kareem();
398
    k1.pre('cook', function() {});
399
    k1.post('cook', function() {});
400

    
401
    var k2 = k1.clone();
402
    assert.deepEqual(['cook'], Object.keys(k2._pres));
403
    assert.deepEqual(['cook'], Object.keys(k2._posts));
404
  
405
```
406

    
407
## merge()
408

    
409
#### It pulls hooks from another Kareem object
410

    
411
```javascript
412
    
413
    var k1 = new Kareem();
414
    var test1 = function() {};
415
    k1.pre('cook', test1);
416
    k1.post('cook', function() {});
417

    
418
    var k2 = new Kareem();
419
    var test2 = function() {};
420
    k2.pre('cook', test2);
421
    var k3 = k2.merge(k1);
422
    assert.equal(k3._pres['cook'].length, 2);
423
    assert.equal(k3._pres['cook'][0].fn, test2);
424
    assert.equal(k3._pres['cook'][1].fn, test1);
425
    assert.equal(k3._posts['cook'].length, 1);
426
  
427
```
428