Javascript / Sails.js控制器等待服务调用异步函数

时间:2015-01-11 11:42:06

标签: javascript node.js asynchronous sails.js

使用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->异步方法调用的适当方式。

1 个答案:

答案 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的解决方案!!