2014-01-22 17 views
2

我想了解有關node.js中的異步模塊的一件事。將對象返回到node.js中的async.each函數

我已經創建了一個函數,它將一個對象從一個表單映射到一個模型對象並返回這個對象。 此對象是帶有一組標籤的視頻。

我的問題是我可以在哪裏返回視頻?我通常知道它是在異步回調函數內,但如果我這樣做,返回的對象是未定義的。 而如果我在整個功能的末尾返回視頻對象,它的作品,但它不安全,因爲我不知道,我的異步完成...

順便說一下,我不明白回調函數傳遞給參數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 
+0

:如果是的話,上面的代碼將做到這一點,否則下面的代碼會工作得更好'async'當你的回調函數根本不是異步的?我真的認爲你想要一個同步['map()'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) – Bergi

回答

2

簡單的答案是,你不能 - 以至少不是通過簡單或明顯的方法。顧名思義,async是一個用於將異步函數調用排入事件循環的庫。所以你的exports.video函數只是啓動一堆異步函數,它們在不可預知的時間範圍內依次執行,然後立即返回。不管你嘗試在你的函數調用的範圍內返回你的視頻對象,這些調用通過async實例化,exports.video函數已經返回。

在這種情況下,它看起來並不像你需要異步函數調用你正在做的事情。我建議你用Underscore的每種方法代替你的異步使用,而這種方法可以同步執行。

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

+0

你完全正確的是歐文。謝謝哥們 *** –

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' 
}); 

順便說一句,我不明白回調函數pas sed async.each的參數並在video.products.push(tag)之後調用; 。 這個函數做什麼?

async.each函數將爲您的數組中的每個項調用上面的'eachTag'函數(第2個參數)。但是因爲它是異步完成的,你可能在函數中做了一些異步操作(命中數據庫/ 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 });