Javascript Node.js出现多个get请求的意外堆栈溢出
我有一个函数,可以从远程服务器或磁盘上的本地缓存获取JSON对象 在一个用例中,我必须使用不同的参数调用这个函数几千次,但是当我这样做时,我会得到最大堆栈溢出错误。我必须在某个地方进行递归调用,但我看不出它可能在哪里,因为我的进程。nextTick函数调用似乎位于正确的位置 我在控制台中没有得到log.error的读数,如果进行了重试请求的递归调用,这一点就很明显了 控制台输出显示重复出现的 (节点)警告:检测到Recursive process.nextTick。这将在节点的下一个版本中中断。请使用setImmediate进行递归延迟 然后 RangeError:超出了最大调用堆栈大小 然后程序退出 关于我可能做错了什么,有人能提供帮助吗?我完全被难住了 下面是调用有问题的函数“tf2inv.loadInventory()”的函数 这里显示的是从缓存解析或从远程服务器请求的函数Javascript Node.js出现多个get请求的意外堆栈溢出,javascript,node.js,stack-overflow,Javascript,Node.js,Stack Overflow,我有一个函数,可以从远程服务器或磁盘上的本地缓存获取JSON对象 在一个用例中,我必须使用不同的参数调用这个函数几千次,但是当我这样做时,我会得到最大堆栈溢出错误。我必须在某个地方进行递归调用,但我看不出它可能在哪里,因为我的进程。nextTick函数调用似乎位于正确的位置 我在控制台中没有得到log.error的读数,如果进行了重试请求的递归调用,这一点就很明显了 控制台输出显示重复出现的 (节点)警告:检测到Recursive process.nextTick。这将在节点的下一个版本中中断。
//tf2inv
var loadInventory = function(force, sid, callback) {
var invLoc = invFolder+sid
if(force) {
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
}
if(fs.existsSync(invLoc)) {
var body = fs.readFileSync(invLoc);
try {
var inventory = JSON.parse(body);
} catch (e) {
fs.unlinkSync(invLoc);
log.error("parsing " + sid+"'s inventory");
loadInventory(true, sid, invFolder, callback);
return;
}
process.nextTick(function() { callback(inventory, sid) })
return;
} else {
var urlPre = "http://api.steampowered.com/IEconItems_440/GetPlayerItems/v0001/?key=";
var urlSidPre = "&steamid=";
var urlInvSuf = "&inventory=yes";
var URL = urlPre+steam_API+urlSidPre+sid+urlInvSuf;
http.get(URL, function (res) {
var body = '';
res.on('data', function (data) {
body+=data;
fs.appendFile(invLoc, data);
});
res.on('end', function() {
try {
inventory = JSON.parse(body);
} catch (e) {
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.error("parsing " + sid+"'s downloaded inventory");
loadInventory(force, sid, invFolder, callback)
return;
}
process.nextTick(function() { callback(inventory, sid) })
return;
});
res.on('error', function (e, socket) {
log.error(sid + " inventory error")
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.debug('Retrying inventory')
loadInventory(force, sid, invFolder, callback);
return;
})
res.on('close', function () {res.emit('end'); log.error('connection closed')})
})
.on('error', function(e) {
log.error(JSON.stringify(e));
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.debug('Retrying inventory')
loadInventory(force, sid, invFolder, callback)
return;
})
}
};
它可能无法解析从服务器返回的主体。然后它立即再次调用自己,再次失败,无限循环并导致堆栈溢出
我建议您不要对失败的解析自动重试—如果它失败一次,很可能再次失败。最好带着错误回调,让调用该错误的编程部分处理错误,或者将错误传递回可以让用户知道有问题的地方。在该catch处理程序中,
loadInventory(true、sid、invFolder、callback)代码>看起来可能是无限递归的。错误的堆栈跟踪是什么?Bergi,谢谢你的帮助。递归调用不会成为问题,因为该调用之前的log.error控制台输出永远不会出现。因此,堆栈跟踪不会显示,因为它是堆栈溢出错误。我的文章中详细介绍了我程序这一部分的控制台输出。Austinen您必须使用调试器并在错误时停止,这样您可以检测当前堆栈。根据记录器的不同,它可能会异步输出错误,这意味着如果进程在输出之前崩溃,您将看不到它。记录器只是console.log的代理,它具有彩色编码的日志子类型。在这种情况下。它是同步的,我会看到控制台记录错误。我看不到这一点,这让我认为问题不在于递归函数调用。当我在家时,我将删除错误处理并确认情况属实。
//tf2inv
var loadInventory = function(force, sid, callback) {
var invLoc = invFolder+sid
if(force) {
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
}
if(fs.existsSync(invLoc)) {
var body = fs.readFileSync(invLoc);
try {
var inventory = JSON.parse(body);
} catch (e) {
fs.unlinkSync(invLoc);
log.error("parsing " + sid+"'s inventory");
loadInventory(true, sid, invFolder, callback);
return;
}
process.nextTick(function() { callback(inventory, sid) })
return;
} else {
var urlPre = "http://api.steampowered.com/IEconItems_440/GetPlayerItems/v0001/?key=";
var urlSidPre = "&steamid=";
var urlInvSuf = "&inventory=yes";
var URL = urlPre+steam_API+urlSidPre+sid+urlInvSuf;
http.get(URL, function (res) {
var body = '';
res.on('data', function (data) {
body+=data;
fs.appendFile(invLoc, data);
});
res.on('end', function() {
try {
inventory = JSON.parse(body);
} catch (e) {
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.error("parsing " + sid+"'s downloaded inventory");
loadInventory(force, sid, invFolder, callback)
return;
}
process.nextTick(function() { callback(inventory, sid) })
return;
});
res.on('error', function (e, socket) {
log.error(sid + " inventory error")
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.debug('Retrying inventory')
loadInventory(force, sid, invFolder, callback);
return;
})
res.on('close', function () {res.emit('end'); log.error('connection closed')})
})
.on('error', function(e) {
log.error(JSON.stringify(e));
if(fs.existsSync(invLoc)) {
fs.unlinkSync(invLoc);
}
log.debug('Retrying inventory')
loadInventory(force, sid, invFolder, callback)
return;
})
}
};