Nodejs简单异步操作管理器

我想我每次开始写博客的第一句话都会是:好久没有写博客了,写一个吧 – -!

最近写nodejs比较多,刚开始的时候碰到的异步的操作比较少,因为想做的东西比较简单,一查api有同步的,为了省事就直接用同步的搞了,慢慢发现这不是个事呀,好好的异步特性不用,非得用同步的,真囧,并且很多东西木有同步的api的。

好!写异步的,慢慢的出现了这种代码。。。

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql.query('xxxx').on('success', function(){
   mysql.query('xxxx').on('success', function(){
        mysql.query('xxxx').on('success', function(){
            mysql.query('xxxx').on('success', function(){
                mysql.query('xxxx').on('success', function(){
                    mysql.query('xxxx').on('success', function(){
                        //let's say fuck
                    });
                });
            });
        });
    });
});

恩,你也看到了,这样下去代码多丑,会像老太太的裹脚布一样了,于是就产生下面的异步操作管理器,小巧精致,嘿嘿,绝对够用,代码的事,用代码说话吧,直接亮代码,如码:

TODO:不够全面,比如说出错的就没有处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/*
 *  异步管理器
 *  author : jser.me
 *
 *  使用方法:
 *     var asyncMg = require('./AsyncManager');
 *     asyncMg
 *     .push(function( next ){
 *         some_aysnc_method().on('success'{
 *            ....
 *            next();
 *         })
 *     })
 *     .push(function( next ){
 *         other_aysnc_method().on('success'{
 *            ....
 *            next();
 *         })
 *     })
 *     .push( ... )
 *     .run() //执行
 *     .on('success', function(){
 *          allThings_is_down();
 *     });
 *
 *     push方法接受数组
 */
 
function typeOf( obj ){
    return Object.prototype.toString.call( obj ).match(/\[object ([^\]]*)\]/)[1];
}
 
function AsyncManager( arg ){
    this.execArrys = [];
    this.push( arg );
}
 
//使用系统带的继承方法
require('util').inherits( AsyncManager, require('events').EventEmitter );
 
//标记成功运行的函数数目
AsyncManager.prototype.succCount = 0;
 
 
//加入
AsyncManager.prototype.push = function( arg ) {
 
        var This = this;
        if( typeOf(arg) == 'Array' ){
            arg.forEach( function(v,i){
               This.execArrys.push( v );
            });
        } else {
               This.execArrys.push( arg );
        }
 
        return this; //链一个
};
 
//执行
AsyncManager.prototype.run = function(){
        var self = this;
 
        if( this.succCount == this.execArrys.length ) {
            //所有函数成功执行后触发事件
            this.emit( 'success' );
        } else {
            this.execArrys[ this.succCount ]( self.run.bind( self ) );
        }
 
        this.succCount++;
        return this; //链一个
};
 
exports = module.exports = function( arg ){
    return new AsyncManager( arg );
}

Random Posts

  1. 建议使用 Step 库

  2. node有一个moduel叫async,也是解决类似的问题,不过我很喜欢用你的方法最后写出来的代码风格。
    有没有考虑加到npm?

Leave a Reply


[ Ctrl + Enter ]