Node.js 简易异步流程控制工具:AsyncManager

作者:后端茶话

时间:2026-10-28

浏览:230

本文介绍了一个轻量级的 Node.js 异步操作管理器 AsyncManager,旨在解决嵌套回调导致的代码可读性下降问题。通过链式 push 方法添加任务,利用 EventEmitter 机制在全部任务完成后触发 success 事件。该实现支持数组批量添加,采用原型继承方式构建,但需注意当前版本尚未包含错误处理逻辑。

文章目录

异步开发背景与问题

近期在 Node.js 开发中,初期因需求简单且部分 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
                    });
                });
            });
        });
    });
});

AsyncManager 设计与实现

正如所见,这种层层嵌套的方式会导致代码极度混乱,如同“回调地狱”。为此,设计了一个小巧且实用的异步操作管理器,具体实现见下方代码。

局限性说明

待完善:目前版本未包含错误处理机制。

代码如下:

/*
* 异步管理器
* 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 );
}

 

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章