Javascript 重新启动节点函数时超出了调用堆栈大小

Javascript 重新启动节点函数时超出了调用堆栈大小,javascript,node.js,loops,timeout,Javascript,Node.js,Loops,Timeout,我正试图克服调用堆栈大小超出了的错误,但运气不好 目标是只要我在type字段中获得music,就重新运行GET请求 //tech: node.js + mongoose //import components const https = require('https'); const options = new URL('https://www.boredapi.com/api/activity'); //obtain data using GET https.get(options, (r

我正试图克服
调用堆栈大小超出了
的错误,但运气不好

目标是只要我在
type
字段中获得
music
,就重新运行GET请求

//tech: node.js + mongoose
//import components
const https = require('https');
const options = new URL('https://www.boredapi.com/api/activity');


//obtain data using GET
https.get(options, (response) => {
  //console.log('statusCode:', response.statusCode);
  //console.log('headers:', response.headers);

  response.on('data', (data) => {
        //process.stdout.write(data);
        apiResult = JSON.parse(data);
        apiResultType = apiResult.type;
        returnDataOutside(data);
  });
 })

.on('error', (error) => {
  console.error(error);
 });


function returnDataOutside(data){
  apiResultType;

  if (apiResultType == 'music') {
    console.log(apiResult);
  } else {
    returnDataOutside(data);
    console.log(apiResult); //Maximum call stack size exceeded
  };
};

函数
returnDataOutside()
正在递归调用自身。如果它第一次没有得到
'music'
apiResultType
,那么它只是不断地调用自己,直到堆栈溢出,再也没有机会得到
music
类型,因为您只是用相同的数据反复调用它

当您没有
音乐
类型时,似乎希望重新运行GET请求,但您的代码没有这样做-它只是反复调用响应函数。因此,相反,您需要将发出GET请求的代码放入一个函数中,并在
apirresulttype
不是您想要的时调用实际发出新GET请求的新函数

此外,您不应该编写像这样的代码,这样的代码会持续不断地攻击某些服务器。您应该有一个最大的尝试次数或一个计时器后退,或者两者都有

而且,您不能仅仅假设
response.on('data',…)
包含一段格式完美的JSON。如果数据不是很小,那么数据可能以任意大小的块到达。它使您需要多个
数据
事件才能获得整个有效负载。而且,这可能适用于快速网络,但不适用于慢速网络或通过某些代理,但不适用于其他网络。相反,您必须累积连接在一起的整个响应(所有发生的
数据
事件)的数据,然后在
结束
事件上处理最终结果

虽然您可以编写普通的
https.get()
代码来为您收集所有结果(在中有一个这样的示例),但只需使用一个更高级别的库来支持一系列有用的东西就容易多了


在这方面,我最喜欢使用的库是,但是有一个替代列表,你可以找到你喜欢的。这些库不仅在您编写任何额外代码时为您累积整个请求,而且它们基于承诺,这使得异步编码更容易,它们还自动为您检查状态代码结果,跟踪重定向等您希望http请求库为您“只处理”许多事情。

您有一个递归函数,它有一个基本大小写检查
apiResultType
,但在调用过程中您从未更改
apiResultType
变量?!谢谢你的回复。有一件事我注意到,一旦返回第一个GET,相同的数据就会像无限循环模式一样一次又一次地被处理。所以,一旦循环检索到第一组数据,它就会被卡住。我还认为aoubt使用
setTimeout
设置间隔以每n秒触发一次。@marcin2x4-该评论让我觉得您不明白您的循环没有执行另一个GET请求。您只需使用完全相同的数据反复调用
returnDataOutside(data)
。因此,如果初始GET请求中的数据不正确,您只需创建一个无限递归循环,最终会破坏堆栈。循环不会触发另一个GET请求。