我有一个循环功能,我正在测试我的一条路线。问题是,当我调用它时,挂起所有Web调用,直到完成该功能。我想知道在处理节点时如何不锁定节点。
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');
}
}
};
答案 0 :(得分:0)
你需要在回调中调用你的tmp变量设置。 App.VERB()是非阻塞的。我不熟悉mongoose,但是所有带有tmp变量的代码似乎都是阻塞的。没有回调,所以变量是逐个设置的,当你写这几千次时变得明显。
答案 1 :(得分: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');
};
然后,在循环中向/ populate /:计数器路由发送100,000个请求。您可以使用另一个节点实例来创建虚假请求,您可以执行以下操作:
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请求时,其他节点实例将被阻止。但处理这些请求时,您的快递实例不会被阻止......
答案 2 :(得分:0)
将其重写为非阻塞并使用回调
即。许多小的快速功能,而不是一个大的慢功能。
你应该尽量避免缓慢的繁重功能。把它分解成小任务。
它'挂起'的原因是因为node.js是单线程的。我建议阅读node.js Event Loop,回调以及如何编写非阻塞。
如果您有许多小功能,快递可以在第一个“仍在运行”时响应请求。可以将事件循环看作是按顺序执行的任务数组。
使用aysnc包.parallel()
或.series()
- 文档和大量示例github repo。如果执行顺序很重要,则使用series();如果不执行,则使用parallel()。
在您的示例中,您希望快速插入100k行。
创建一个插入一行的函数,并在完成后调用next()回调函数。
创建一个运行res.send()
的完成函数
使用async.times()
执行创建功能,然后在完成运行完成功能时使用。
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
});