У меня есть приложение, которое я пишу в Node.js, которое должно выполнить множество конфигураций и вызовов базы данных для обработки пользовательских данных. У меня проблема в том, что после 11 800+ вызовов функций Node выдаст ошибку и выйдет из процесса.
Ошибка говорит: RangeError: Превышен максимальный размер стека вызовов
Мне любопытно, возникла ли у кого-нибудь еще такая ситуация и узнать, как они справились с этим. Я уже начал разбивать свой код на пару дополнительных рабочих файлов, но даже в этом случае каждый раз, когда я обрабатываю узел данных, ему нужно коснуться 2 баз данных (не более 25 вызовов для обновления различных таблиц) и выполнить ряд проверок санации. .
Я полностью готов признать, что, возможно, я делаю что-то неоптимальное, если это так, но был бы признателен за некоторые рекомендации, если есть более оптимальный способ.
Вот пример кода, который я запускаю на данных:
app.post('/initspeaker', function(req, res) {
// if the Admin ID is not present ignore
if(req.body.xyzid!=config.adminid) {
res.send( {} );
return;
}
var gcnt = 0, dbsize = 0, goutput = [], goutputdata = [], xyzuserdataCallers = [];
xyz.loadbatchfile( xyz.getbatchurl("speakers", "csv"), function(data) {
var parsed = csv.parse(data);
console.log("lexicon", parsed[0]);
for(var i=1;i<parsed.length;i++) {
if(typeof parsed[i][0] != 'undefined' && parsed[i][0]!='name') {
var xyzevent = require('./lib/model/xyz_speaker').create(parsed[i], parsed[0]);
xyzevent.isPresenter = true;
goutput.push(xyzevent);
}
}
dbsize = goutput.length;
xyzuserdataCallers = [new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata(),
new xyzuserdata()
];
// insert all Scheduled Items into the DB
xyzuserdataCallers[0].sendSpeakerData(goutput[0]);
for(var i=1;i<xyzuserdataCallers;i++) {
xyzuserdataCallers[i].sendSpeakerData(8008);
}
//sendSpeakerData(goutput[0]);
});
var callback = function(data, func) {
//console.log(data);
if(data && data!=8008) {
if(gcnt>=dbsize) {
res.send("done");
} else {
gcnt++;
func.sendSpeakerData(goutput[gcnt]);
}
} else {
gcnt++;
func.sendSpeakerData(goutput[gcnt]);
}
};
// callback loop for fetching registrants for events from SMW
var xyzuserdata = function() {};
xyzuserdata.prototype.sendSpeakerData = function(data) {
var thisfunc = this;
if(data && data!=8008) {
//console.log('creating user from data', gcnt, dbsize);
var userdata = require('./lib/model/user').create(data.toObject());
var speakerdata = userdata.toObject();
speakerdata.uid = uuid.v1();
speakerdata.isPresenter = true;
couchdb.insert(speakerdata, config.couch.db.user, function($data) {
if($data==false) {
// if this fails it is probably due to a UID colliding
console.log("*** trying user data again ***");
speakerdata.uid = uuid.v1();
arguments.callee( speakerdata );
} else {
callback($data, thisfunc);
}
});
} else {
gcnt++;
arguments.callee(goutput[gcnt]);
}
};
});
Здесь определены пара классов и предметов, которые требуют некоторого введения:
- Я использую Express.js + хостинг CouchDB, и это отвечает на запрос POST
- Существует класс синтаксического анализатора CSV, который загружает список событий, которые управляют извлечением данных о динамике
- Каждое событие может иметь n пользователей (в настоящее время около 8K пользователей для всех событий)
- Я использую шаблон, который загружает все данные / пользователей, прежде чем пытаться проанализировать какие-либо из них
- Каждый загруженный пользователь (внешний источник данных) преобразуется в объект, который я могу использовать, а также очищается (полоски и т. Д.)
- Каждый пользователь затем вставляется в CouchDB
Этот код работает в приложении, но через некоторое время я получаю сообщение о том, что было сделано более 11 800 звонков и приложение перестало работать. Это не ошибка, которая содержит трассировку стека, как если бы это была ошибка кода, она завершается из-за количества выполняемых вызовов.
Опять же, любая помощь / комментарий / направление будет приветствоваться.