我想我每次开始写博客的第一句话都会是:好久没有写博客了,写一个吧 – -!
最近写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 ); } |
建议使用 Step 库
node有一个moduel叫async,也是解决类似的问题,不过我很喜欢用你的方法最后写出来的代码风格。
有没有考虑加到npm?