我正在尝试处理一个大型数组,但该对象有时会很大,以至于它会破坏服务器:
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory
我可以通过node --max-old-space-size=100
然后运行我的进程在本地重现这个。没有设置此选项,它可以正常工作。
这是代码中断的部分
function setManagers(json){
return Q.all(json.map(function(obj){
return getUserByUsername(obj.username)
.then(function(user){
console.log('got here'); //never hits
...
function getUserByUsername(username){
console.log('getting user'); //hits
return UserModel.findOneQ({username:username})
.then(function(user){
console.log('search finished'); //never hits
if(user){
console.log('got user');
return Q(user);
}else{
console.log('no user');
return Q.reject({message:'user ' + username + ' could not be found locally'});
}
});
}
我认为这个问题是由于它是一个巨大的数组,其长度超过5000
如果我要删除限制内存的选项,或者使用较小的数据集,那就可以了。
有没有简单的方法可以避免此错误?
答案 0 :(得分:0)
问题是你同时进行了太多的数据库调用。
我会更改你的逻辑,向数据库发送一个排序字符串,其中所有用户名都用逗号连接,我会立即得到所有用户。然后,我会遍历这些用户,并对您从数据库中收到的用户做任何事情。
另一个不会突破当前逻辑的解决方案是逐个执行数据库操作,例如,使用promise-while:
function pwhile(condition, body) {
var done = Q.defer();
function loop() {
if (!condition())
return done.resolve();
Q.when(body(), loop, done.reject);
}
Q.nextTick(loop);
return done.promise;
}
function setManagers(json) {
var i = 0;
return pwhile(function() { i < json.length; }, function() {
var p = getUserByUsername(json[i].username);
i++;
return p;
});
}