0

我有一个循环功能,我正在测试我的一条路线。问题是当我调用它时,它会挂起所有网络调用,直到它完成该功能。我想知道如何在处理节点时不锁定节点。

app.get('/populate', routes.populate);

exports.populate = function(req, res, next){

    for(i = 0; i < 100000; i++){
        var tmp = new Encounters();

        tmp.kareoId = '1234'; //mock.Address.zipCode();

        tmp.patient.fullName = 'Vartan Arabyan'; //mock.Name.findName();
        tmp.patient.dob = Date.now();
        tmp.patient.kareoId = '12312'; //mock.Address.zipCode();

        tmp.physician.fullName = "Dr." + 'Vartan Arabyan'; //mock.Name.findName();
        tmp.physician.kareoId = '12312'; //mock.Address.zipCode();

        tmp.appointmentType = "NCV Upper";
        tmp.appointment = Date.now();

        tmp.save(function(err){
            if (err) throw err;
        });

        if(i == 99999){
            res.send(200, 'Fake Data Loaded');
        }
    }
};
4

3 回答 3

0

Rewrite it to be non-blocking and use callbacks

ie. lots of small quick functions rather than one large slow function.

You should try to avoid slow heavy functions. Break it up into small tasks.

The reason it 'hangs' is because node.js is single threaded. I recommend reading up on the node.js Event Loop, callbacks and how to write non-blocking.

If you have lots of small functions, express can respond to requests while the first is 'still running'. Think of the event loop like an array of tasks that are executed in order.

Use the aysnc package .parallel() or .series() - documentation and heaps of examples on their github repo. Use series() if execution order is important and parallel() if not.

In your example, you want to quickly insert 100k rows. Create a function that inserts one row and calls a next() callback function when it's finished. Create a done function that runs your res.send() Use async.times() to execute the create functions then when finished runs the done function.

See async.times() documentation on their github repo:

// Pretend this is some complicated async factory
var createUser = function(id, callback) {
  callback(null, {
    id: 'user' + id
  })
}
// generate 5 users
async.times(5, function(n, next){
    createUser(n, function(err, user) {
      next(err, user)
    })
}, function(err, users) {
  // we should now have 5 users
});
于 2013-05-29T04:19:16.730 回答
0

此循环阻塞事件循环,直到它迭代 100,000 次。试试这个:

app.get('/populate/:counter', routes.populate);

exports.populate = function(req, res, next){

     var tmp = new Encounters();

     tmp.kareoId = '1234'; //mock.Address.zipCode();

     tmp.patient.fullName = 'Vartan Arabyan'; //mock.Name.findName();
     tmp.patient.dob = Date.now();
     tmp.patient.kareoId = '12312'; //mock.Address.zipCode();

     tmp.physician.fullName = "Dr." + 'Vartan Arabyan'; //mock.Name.findName();
     tmp.physician.kareoId = '12312'; //mock.Address.zipCode();
     tmp.appointmentType = "NCV Upper";
     tmp.appointment = Date.now();

     tmp.save(function(err){
         if (err) throw err;
     });

     if(req.param('counter') == 99999){
         return res.send(400, 'Fake Data Loaded');
     }
     res.send(200, 'Send me more Data');
};

然后,循环发送 100,000 个请求到 /populate/:counter 路由。您可以使用另一个节点实例来创建虚假请求,您可以执行以下操作:

var http = require('http');

var options = {
    hostname: 'localhost',
    port: 3000,  // I assumed that your express is running on port 3000...
    method: 'GET'
};

var req;
for (var i = 0; i < 100000; i++) {
    options.path = '/populate/' + i;
    req = http.request(options, function(res) {
        res.setEncoding('utf8');
        if (res.statusCode == 400) {
            // Handle 'Fake Data Loaded'
            console.log('Fake data loaded..');
        }
        else 
            console.log('Still not there yet! Send more data...') 
        res.on('data', function (data) {
            console.log(data);
        });
    });

    req.on('error', function(e) {
        console.log('problem with request: ' + e.message);
    });

    req.end();  
};

您必须注意,在发出 100,000 个 http 请求时,其他节点实例将被阻止。但是在处理这些请求时,您的 express 实例不会被阻止......

于 2013-05-29T04:15:45.410 回答
0

您需要在回调中调用您的 tmp 变量设置。App.VERB() 是非阻塞的。我不熟悉猫鼬,但是所有带有 tmp 变量的代码似乎都是阻塞的。没有回调,因此变量被一一设置,当您编写数千次时会变得明显。

于 2013-05-29T03:26:08.510 回答