发布一个异步控制流的Nodejs模块xchain
发布一个异步控制流的Nodejs模块xchain
[xchain]是用于简化异步控制流的库,已经在npm上注册了。至于有什么用,用过[Step]的人会明白,但因为我觉得[Step]的异常处理方式是存在一定问题的。这个库的接口设计经过了很久的思考,应该是很简单且实用的。
用代码简要地说明:
var xchain = require('xchain'); var util = require('util');
xchain( // 在这个圆括号内的作为xchain的参数的两个函数 // 是并行执行的。 function(next) { setTimeout(function(){ next.foo = 1; util.log(‘next.foo completed’); next(); // 表示这个异步操作完成 }, 1000); // 模拟一个用时1秒的异步操作 }, function(next) { setTimeout(function() { next.bar = 2; util.log(‘next.bar completed’); next(); }, 2000); // 模拟一个用时2秒的异步操作 } )( // xchain()返回的也是一个函数,用法和上面相同, // 用链式的表达式来表示依赖关系 function(next) { util.log(‘foo=’, next.foo); util.log(‘bar=’, next.bar); throw { error : 1 }; // 抛出的异常会被传给run方法的回调捕获 }, function(next) { next(); } )( function(next) { throw { error : 2 }; } )( function(next) { // 不会执行到此处,自行揣摩传给run方法的回调 } ).run(function(err, next) { if (err.error == 1) next(); // 模拟一个可以恢复的错误 // 其他错误不处理 });
###简单的总结
- 通过链式表达式的形式描述异步操作的依赖关系和并行关系,应该是比较简洁而清晰的。
- 异步操作完成时将
next
当作函数来调用,以通知xchain当前异步操作完成,当所有并行的操作完成是,xchain会执行下一个(批)异步操作。 - 为了方便数据的通信,也可以将next当作普通的对象使用(如有必要,也可以使用闭包)。
- 在构建好异步控制流之后,调用
run()
方法开始从上而下执行。可以给run()
方法传递一个异常处理函数,可以在异常处理函数中恢复控制流,或者中断控制流的执行(如不提供异常处理函数,一旦发生异常,默认按照依赖关系停止异步控制流的执行)。
此外,欢迎fork,comment和patch。 [xchain]: http://github.com/thynson/xchain [Step]: http://github.com/creationix/step
发布一个异步控制流的Node.js模块xchain
今天,我发布了一个新的Node.js模块——xchain
,它旨在简化异步控制流的管理。该模块已经在npm上注册,并且已经在一些项目中得到了应用。
用途
如果你之前使用过Step
库,你可能会对xchain
有所了解。虽然Step
非常强大,但我发现它的异常处理机制存在一些问题。因此,我设计了xchain
,希望它能够更加简单且实用。
示例代码
下面是一个简单的例子,展示了如何使用xchain
来管理异步操作:
var xchain = require('xchain');
var util = require('util');
xchain(
// 在这个圆括号内的两个函数是并行执行的
function(next) {
setTimeout(function(){
next.foo = 1;
util.log('next.foo completed');
next(); // 表示这个异步操作完成
}, 1000); // 模拟一个用时1秒的异步操作
},
function(next) {
setTimeout(function() {
next.bar = 2;
util.log('next.bar completed');
next();
}, 2000); // 模拟一个用时2秒的异步操作
}
)(
// xchain()返回的也是一个函数,用法和上面相同,
// 用链式的表达式来表示依赖关系
function(next) {
util.log('foo=', next.foo);
util.log('bar=', next.bar);
throw { error: 1 }; // 抛出的异常会被传给run方法的回调捕获
},
function(next) {
next();
}
)(
function(next) {
throw { error: 2 };
}
)(
function(next) {
// 不会执行到此处,自行揣摩传给run方法的回调
}
).run(function(err, next) {
if (err && err.error === 1) {
next(); // 模拟一个可以恢复的错误
}
// 其他错误不处理
});
简单总结
-
链式表达式:通过链式表达式的形式描述异步操作的依赖关系和并行关系,使得代码结构更加简洁和清晰。
-
异步操作完成通知:异步操作完成时,将
next
当作函数来调用,以通知xchain
当前异步操作已完成。当所有并行的操作完成后,xchain
会执行下一个(批)异步操作。 -
数据通信:为了方便数据的通信,也可以将
next
当作普通的对象使用(如有必要,也可以使用闭包)。 -
运行控制流:在构建好异步控制流之后,调用
run()
方法开始从上而下执行。可以给run()
方法传递一个异常处理函数,在异常处理函数中恢复控制流或中断控制流的执行。如果不提供异常处理函数,一旦发生异常,默认按照依赖关系停止异步控制流的执行。
总结
xchain
旨在简化异步控制流的管理,提供了一种更简洁、更灵活的方式来处理复杂的异步操作。欢迎大家试用、评论和贡献代码!
能简单介绍下你这个模块的工作流程吗?
感觉很高深,我想知道这个和老赵的wind.js还有eventproxy是什么关系呢?
这个不合适吧!用setTimeout来模拟执行时间不大可取! 毕竟执行一段代码你不知道是1秒还是2秒还是0.2秒、甚至20ms! 当然这是解决异步的一种方法,但是个人觉得不怎么靠谱!
汗,这是作者的示例,不是实现机制~ settimeout只是用来模拟一个异步操作
看github上的源代码吧,应该不是很难理解。
还没去看他的代码,但我感觉应该是使用递归实现的
var Step = require('step');
var con = require('console');
Step(
function() {
var next1 = this.parallel();
var next2 = this.parallel();
setTimeout(function() {
next1({ error : 1}, 5);
}, 100);
setTimeout(function() {
next2({ error : 2}, 20);
}, 200);
},
function(err, a, b) {
con.log(err);
con.log(a);
con.log(b);
}
)
第一个异常{error : 1 }
会被覆盖掉.
var xchain = require('xchain');
var con = require('console');
xchain(
function(next) {
setTimeout(function() {
next({error : 1}); //异步调用中异常,不能用throw
}, 100);
},
function(next) {
next({error : 2});// 等价于 throw {error : 2};
},
function(next) {
throw {error : 3};//等价于 next({error : 3});
}
)(
function(next) {
}
).run(function(err, next) {
con.log(err);
next();
});
传给run方法的回调针对不同的异常会被调用三次
nodejs的技术欢迎加群聊262658247
想了解一下你的库和async库中的waterfall有什么差异?
想知道这样的代码用xchain有什么优势, 如果这个例子不能说明问题,能不能举个体现xchain优势的例子, 老赵看到了也说说wind的?
arr = [1,2,3,4,5,6,7,8,9];
async.reduce(arr, 0, function(result, item, cb){ cb(item > 5 ? 'stopped on '+item : null , result + item); }, function(err, result){ console.log(‘reduce’, err, result); });
async.waterfall([ function(cb){ cb(null, arr.map(function(item){ return item + 1; })) }, function(result, cb){ if(result[0] != 2) cb(null, result.map(function(item){ return item + 1; })) else cb(‘stopped on step 2’, result); }, function(result, cb){ cb(null, result.map(function(item){ return item + 1; })) } ], function(err, result){ console.log(‘waterfall’, err, result); })
另外给回帖功能提几个建议:
- 提交了以后自己干嘛不能修改?
- 能@某人就好了,和微博一样,github上的回复好像也有这种功能,就是引起某人注意
async.reduce
和这个不是一个东西。
async.waterfall
是完全串行的,目的也和xchain
不一样,只有async.auto
才有可比性。
没懂reduce要干嘛的……waterfall不就是串行嘛,用Wind.js写就是:
var r1 = arr.map(function(item) { return item + 1; })); if (r1[0] == 2) throw 'stopped on step 2';
var r2 = r1.map(function(item) { return item + 1; }); var r3 = r2.map(function(item) { return item + 1; });
return r3;
不过你异步的点在哪里?
api确实比eventproxy要好。。
以下是关于发布 xchain
Node.js 模块的内容:
xchain
是一个用于简化异步控制流的库,已在 npm 上注册。该库针对 Step 库的异常处理方式进行了改进,并经过长时间的思考设计,使得接口更加简单和实用。
以下是 xchain
的基本使用示例:
var xchain = require('xchain');
var util = require('util');
xchain(
// 这两个函数并行执行
function(next) {
setTimeout(function(){
next.foo = 1;
util.log('next.foo completed');
next(); // 表示当前操作完成
}, 1000);
},
function(next) {
setTimeout(function() {
next.bar = 2;
util.log('next.bar completed');
next();
}, 2000);
}
)(
// 依次执行后续的异步操作
function(next) {
util.log('foo=', this.foo);
util.log('bar=', this.bar);
throw { error: 1 };
},
function(next) {
next();
}
)(
function(next) {
throw { error: 2 };
}
)(
function(next) {
// 不会执行到这里
}
).run(function(err, next) {
if (err && err.error == 1) {
next(); // 恢复错误
}
// 其他错误默认停止执行
});
简单总结:
- 使用链式表达式描述异步操作的依赖关系和并行关系,使代码简洁清晰。
- 异步操作完成时调用
next()
函数通知xchain
当前操作完成。 - 可以将
next
对象当作普通对象使用,以便于数据传递。 - 调用
run()
方法开始执行整个异步控制流,可传递异常处理函数来恢复或中断控制流。