一个简单的Node.js异步操作管理器分享

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

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

  

复制代码 代码如下:

  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:不够全面,比如说出错的就没有处理

  

复制代码 代码如下:

  /*

  *  异步管理器

  *  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 );

  }