2015-09-28 53 views
0

我想將MongoDB數據庫作爲child_process運行,因爲某些數據庫操作需要很長時間,我不希望應用程序的其餘部分凍結。是否可以在node.js中結合回調和事件

我可以將數據庫代碼放入一個模塊,該模塊可以通過child_process中的事件發射器進行反應和恢復。

下面是一個簡化版本(DB-process.js)代碼:

var MongoClient = require('mongodb').MongoClient; 
var url = 'mongodb://localhost:27017/myproject'; 
var db = null; 

MongoClient.connect(url, function(err, database) { 
    if(err){ 
     console.warn('Connection to MongoDB failed.'); 
    }else{ 
     db = database; 
     console.log('Connected to MongoDB.'); 
    } 
}); 

process.on('message', function(msg) { 
    switch(msg.name){ 
     case 'getRecord': 
      var collection = db.collection('SomeTable'); 
      collection.find({id: 'someId').toArray(function(err, docs) { 
       if(!err) process.send{'name': 'getRecord', record: records[0]}); 
      }); 
      break; 
     case 'saveRecord': 
      // Code here... 
      break; 
    } 
}); 

的挑戰是,我希望能夠通過傳遞迴調函數使用的數據庫模塊。這將使它更容易在我所有的其他模塊中使用。但是,我怎樣才能把一個事件的變量放入回調函數中呢?這甚至有可能嗎?

下面顯示我的一個簡化版本未完成的企圖(DB-controller.js):

var childProcess = require('child_process'); 
var dbProcess = childProcess.fork('./db-process.js'); 

dbProcess.on('message', function(msg) { 
    switch(msg.name){ 
     case 'getRecord': 
      var record = msg.record; 
      break; 
     case 'saveRecord': 
      // Handling here... 
      break; 
    } 
});  

var controller = {};  

controller.getRecord = function(onQueryDone){ 
    dbProcess.send({name: 'getRecord'}); 
    // How to call the callback function with data when it is received? Basicly want the record variable from the switch. 
    onQueryDone(record); 
}; 

controller.saveRecord = function(record, onQueryDone){ 
    dbProcess.send({name: 'saveRecord'}); 
    // Handling... 
}; 

module.exports = controller; 

所以我希望能夠利用這個模塊是這樣的:

var dbController = require('./db-controller.js'); 

dbController.getRecord(function(record)){ 
    // Do something with record... 
}); 

有關如何完成此任何想法?

回答

0

據我所知,你不能通過節點實例(主和分叉實例)之間的回調,但你可以傳遞數據。

你在你的案例中使用的是一個工作者池模塊,工作者實例將處理所有的數據庫查詢,而主(池實例)將數據發送給這些工作者,並在他們完成。

這是我在github forked-worker-pool上提供的一個,但在npm上還有一些其他的選擇。

0

另一種選擇是完全解耦你的過程。我以前在亞馬遜上使用過SQS,我將數據放入一個隊列,還有另一個服務器/進程監聽這些項目,喚醒並處理它們。這是一個非常簡單的模型。如果您不在AWS上,可以使用類似rabbitmq的東西。這樣,您的應用服務器永遠不會被阻塞,因爲它只是將數據轉儲到隊列並繼續。

相關問題