使用asnyc调用等待Javascript函数完成是非常简单的,但似乎不太清楚如何处理调用服务器的Controller,后者又调用异步函数。
我们假设我有一个简单的异步方法:
foo.fooMethod( {format: _format, stuff: _stuff },
function( error, response, body )
{
if ( error )
{
sails.log( error );
res.send( "Error " + error, 500 );
}
res.send( body, 200 );
});
在这种情况下,如果我将其置于控制器中,我的异步调用将正常工作,因为回调将导致在最终控制函数回调时发送响应。但是,如果我把它放入服务中,我会遇到一个更有趣的问题。
在MyService内部,我为serviceCall定义了这个导出
exports.serviceCall = function(options) {
async.auto(
{
test: function( callback )
{
foo.fooMethod( {format: _format, stuff: _stuff },
function( error, response, body )
{
sails.log("Finished with call");
if ( error )
{
sails.log( error );
callback( error );
//res.send( "Error " + error, 500 );
}
callback( null, body );
//res.send( body, 200 )
});
}
},
function(err, result)
{
sails.log("Returrning");
return result;
}
);
};
问题是如果我从控制器调用它,显然会发生这种情况。 Service调用将立即返回,因此我无法从serviceCall获取响应,以便我可以将此响应发送给用户。由于我不想在node.js中阻塞,因此不清楚从Controller-> Service->异步方法调用的适当方式。
答案 0 :(得分:1)
在与IRC上#sailsjs的精彩社区聊天时,我找到了一个比回传传递回调更好的答案(讨厌那种设计模式)。
var Promise = require('bluebird');
exports.serviceCall = function(options) {
parameters = {
format: options.format,
stuff: options.stuff
}
return new Promise( function( resolve, reject )
{
foo.fooMethod( parameters
function( error, response, body )
{
sails.log("Finished with call");
if ( error )
{
sails.log( error );
throw error;
}
else
{
return resolve(response.results);
}
});
})
};
};

然后可以直接调用
SomeService.serviceCall(options).then(function(results){
res.json(results);
})

这是使用sailsjs做这些事情的合适设计模式,它运行得非常好,没有不断传递回调的愚蠢!特别感谢robdubya的解决方案!!