2014-02-12 21 views
0

我想寫一個應用程序的節點,將首先解析一個json stirng,驗證如果該字符串包含所需的鍵/值對,並最終對該數據做更多的處理。我們使用async.waterfall來調用我們的函數,因爲結果需要從一個函數傳遞到下一個函數。節點eventEmitter的使用和範圍內的async.waterfall調用

我不斷遇到的問題是我相信的範圍。我想發出一個'錯誤'或'成功'消息作爲瀑布最終回調的一部分,但無論我做什麼,我似乎都無法捕捉到這條消息。我的檔案的重要組成部分看起來是這樣的:

var MetadataIngester = function() { 
    var status, returnValue; 
    eventEmitter.call(this); 
} 

util.inherits(MetadataIngester, eventEmitter); 

MetadataIngester.prototype.sendEvent = function(eventType, eventMessage) { 
    this.emit(eventType, eventMessage); 
} 

MetadataIngester.prototype.clobber = function(itemString) { 
    var self = this; 
    var asyncParseItem = self.parseItem; 
    var asyncValidateItem = self.validateItem; 
    var asyncSendvent = self.sendEvent; 
    async.waterfall(
     [ 
      function(callback) { 
       asyncParseItem(itemString, callback); 
      }, 
      asyncValidateItem 
     ], 
     function(err, result) { 
      if (err) { 
       asyncSendEvent.call(self, 'wtf', result); 
      } else { 
       asyncSendEvent.call(self, 'success', { 
        'remedia_id': 123 
       }); 
      } 
     } 
    ); 

爲了測試這一點,我做了以下內容:

describe("#clobber", function() { 
    it('should emit an error event if item has not been inserted', function() { 
     item = "{}"; 
     metadata.on('wtf', errorSpy); 
     metadata.clobber(item); 
     expect(errorSpy).to.have.been.called; 
    }); 


}); 

describe("#sendEvent", function() { 
    it('should emit an wtf event if an error event type is passed in', function() { 
     metadata.on('wtf', errorSpy); 
     metadata.sendEvent('wtf', {'ihateyou': 'wtf'}); 
     expect(errorSpy).to.have.been.called; 
    }); 
}); 

當我運行的第一個測試,該事件被髮出,但間諜永遠不會被調用。但是,如果我像第二次測試那樣直接調用發出事件的函數,那麼它就可以正常工作,我不知道爲什麼。我需要獲取測試文件捕獲的事件,因爲最終我將使用此MetadataIngester和一個將消息從隊列中拉出的隊列,並且該消費者調用此文件並期望返回事件,以便知道下一步該怎麼做。

任何幫助將不勝感激。

+0

注'變種asyncSendvent'是不同於'asyncSendEvent'後來被稱爲拼寫時。 – Kenan

+0

爲了更好地爲您提供幫助,最好查看您所調用的功能以及如何定義間諜。也許你可以創建一個小提琴?也許這只是一個範圍問題,我提供了一個能夠編寫代碼示例的答案。 – Sonata

回答

0

如果您想保留範圍在回調中,請使用Function.bind。這樣可以使你的代碼更簡潔(沒有魔法selfthat等):

async.waterfall([ 
    function(callback) { 
     this.parseItem(itemString, callback); 
    }.bind(this), 
    this.validateItem 
], function(err, result) { 
    if (err) { 
     this.endEvent('wtf', result); 
    } else { 
     this.sendEvent('success', { 
      'remedia_id': 123 
     }.bind(this)); 
    } 
}.bind(this));