将对象返回到node.js中的async.each函数

时间:2014-01-22 12:21:02

标签: javascript node.js asynchronous

我想了解node.js中的异步模块。

我创建了一个函数,将对象从表单映射到模型对象并返回此对象。 该对象是带有标签数组的视频。

我的问题是我在哪里可以退回视频?我知道它通常在异步回调函数中,但如果我这样做,返回的对象是未定义的。 如果我在整个函数结束时返回视频对象,它可以工作,但是不安全,因为我不确定,我的异步已经完成......

顺便说一句,我不理解在async.each和。的参数中传递的回调函数 在video.products.push(tag);之后调用。这个功能有什么作用?

此致

我的mapping.js中的

 exports.video = function(object) {

        var video = new Video();            
        video.name = object.name;   
        video.products = [];

        async.each(object.tags, function(tago, callback) {

                            tag = {
                            "name" : tago.name
                                 }


                            video.products.push(tag);
                            callback();

                        } ,
                   function(err) {
                            if( err ) {
                        console.log('Error' + error);
                                throw err;  
                            }

                          logger.debug("into async" + video);

                    }

                    );

           logger.debug("end function " );
            **//return video;**

     }

在我的video.js中:

 var video = mapping.video(object); 
 logger.debug(video);  // return undefined

2 个答案:

答案 0 :(得分:2)

简单的答案是你不能 - 至少不是通过简单或明显的方法。顾名思义,async是一个用于将异步函数调用排队到事件循环中的库。所以你的exports.video函数简单地启动了一堆异步函数,它们在一个不可预测的时间帧上一个接一个地执行,然后立即返回。无论你在何处尝试在由async实例化的函数调用范围内返回视频对象,exports.video函数都已经返回。

在这种情况下,你似乎不需要异步函数调用你正在做的事情。我建议你用像Underscore的每个方法替换你的异步,这个方法是同步执行的。

http://documentcloud.github.io/underscore/#each

答案 1 :(得分:2)

您需要为exports.video函数定义一个回调,例如..

exports.video = function(object, callback) {
    // video code (snip)...

   async.each(object.tags,
       function eachTag(tag, done) {
           // code run for each tag object (snip)...
           done();
       },
       function finished(err) {
           // code run at the end (snip)...

           callback(thingThatsReturned);
       });
};

......并且这样称呼它:

var videoUtils = require('videoUtils');
var tags = getTags();

videoUtils.video({ tags: tags }, function(thingThatsReturned) {
   // do something with 'thingThatsReturned'
});

  

顺便说一句,我不明白传入的回调函数   参数async.each并在video.products.push(tag)之后调用; 。   这个功能有什么作用?

async.each函数将为数组中的每个项调用上面的'eachTag'函数(第二个参数)。但是因为它是异步完成的,你可能在函数中执行其他异步操作(点击数据库/ api等),它需要知道该特定数组项的函数何时完成。调用done()告诉async.each函数已经完成处理。一旦所有函数都完成处理(它们都被称为done()),async.each将运行上面的'finished'函数(第三个参数)。

对于Node.js来说,这是非常标准的异步内容,但是首先让它们先解决它是很棘手的。挂在那里: - )


编辑:您的代码看起来没有做任何异步操作。如果是,那么上面的代码将是这样做的方式,否则以下代码将更好地工作:

exports.video = function(object) {
    // video code (snip)...

    if (Array.isArray(object.tags)) {
        object.tags.forEach(function eachTag(tag) {
            // code run for each tag object (snip)...
        });
    }

    return thingThatsReturned;
};

......并称之为......

var videoUtils = require('videoUtils');
var tags = getTags();

var thingThatsReturned = videoUtils.video({ tags: tags });