假设我想发送电子邮件然后更新数据库,这两个操作都是异步的。这就是我通常会写它的方式。
send_email(function(err, id){
if(err){
console.log("error");
}else{
update_database(id,function(err, id){
if(err){
console.log("error");
}else{
console.log("success");
}
});
}
});
我想用中间件来做这件事。
var mid = {};
mid.send_email = function(){
return function(next){
send_email(function(err,id){
if(err){
console.log("error");
}else{
next(id);
}
});
}
}
mid.update_database = function(){
return function(id,next){
update_database(id,function(err,id){
if(err){
console.log("error");
}else{
next(id);
}
});
}
}
mid.success = function(){
return function(id,next){
console.log("success")
next(id);
}
}
堆叠中间件。
middleware.use(mid.send_email());
middleware.use(mid.update_database());
middleware.use(mid.success());
手头有两个主要问题。
next()
?答案 0 :(得分:5)
您想要的是能够处理异步控制流程。很多js库可以帮助您实现这一目标。您可以使用Async
函数尝试waterfall
库,因为您希望能够将变量传递给将要执行的下一个函数:
https://github.com/caolan/async#waterfall
“运行一系列函数,每个函数都将它们的结果传递给数组中的下一个。但是,如果任何函数将错误传递给回调,则不执行下一个函数,并立即调用主回调错误。“
示例:
async.waterfall([
function(callback){
callback(null, 'one', 'two');
},
function(arg1, arg2, callback){
callback(null, 'three');
},
function(arg1, callback){
// arg1 now equals 'three'
callback(null, 'done');
}
], function (err, result) {
// result now equals 'done'
});
答案 1 :(得分:1)
您可以创建如下文件:
module.exports = function (){
function sendEmail(doneCallback){
// do your stuff, then when you are done:
if(!err){
doneCallback(whatever,args,you,need);
}
}
function updateDB(success){
// do your stuff, then when you are done:
success(whatever,args,you,need);
}
return {
send: sendEmail,
update: updateDB
};
};
然后在server.js
:
var lib = require('./mylib.js');
lib.send(function(result){
console.log(result);
});
这是一个类似的模式,它可能会让你更好地了解我的意思。它由图书馆烘焙function
并将其传递给任何需要连锁的人,就像这样(更多的是脚踏实地的例子,这次是客户端):
ui.bistate($('#mybutton'), function(restore){
$.ajax({
url: '/api/1.0/catfood',
type: 'PUT',
data: {
catfood: {
price: 1.23,
name: 'cheap',
text: 'Catzy'
}
}
}).done(function(res){
// stuff with res
restore();
});
});
并且在库中,这是restore
的提供方式:
var ui = function(){
function bistate(button, action) {
var originalText = buttonText.data('text'),
disabledText = buttonText.data('text-disabled');
function restore(){
button.prop('disabled', false);
button.text(originalText);
}
function disable(){
button.prop('disabled', true);
button.text(disabledText);
}
button.on('click', function(){
disable();
action(restore);
});
restore();
}
return {
bistate: bistate
};
}();
允许消费者控制当他想要恢复按钮的流程,并重新使库不必处理消费者想要在其间进行异步操作的复杂情况。
一般来说,重点是:来回传递回调是巨大而不是足够广泛。
答案 2 :(得分:0)
我一直在工作中使用Queue.js。