Javascript setInterval()函数正在控制台上运行,但在一次api命中后,浏览器上的数据不会更新

Javascript setInterval()函数正在控制台上运行,但在一次api命中后,浏览器上的数据不会更新,javascript,node.js,api,express,Javascript,Node.js,Api,Express,我使用了一个远程api来构建自己的NodeJSAPI。 我想让客户点击我的节点API,而不是远程API,以防止远程API上的加载过度 远程api的板球分数每30秒更新一次,因此,我想在30秒内刷新远程api,并在我自己的节点api上更新数据,而不受影响 所以我在远程api上使用了setInterval()函数 const express = require("express"); const app = express(); const request = require("request");

我使用了一个远程api来构建自己的NodeJSAPI。 我想让客户点击我的节点API,而不是远程API,以防止远程API上的加载过度

远程api的板球分数每30秒更新一次,因此,我想在30秒内刷新远程api,并在我自己的节点api上更新数据,而不受影响

所以我在远程api上使用了setInterval()函数

const express = require("express");
const app = express();
const request = require("request");
const url = "http://cricscore-api.appspot.com/csa";

app.get("/getTeam/:id", (req, res) => {
  res.setHeader("content-type", "text/json");
  setInterval(function() {
    const id = req.params.id;
    const purl = url + "?id=" + id;
    request(purl, function(error, response, body) {
      console.log("error:", error);
      console.log("statusCode:", response && response.statusCode);
      console.log(body);
      res.end(body);
      console.log(res);
    });
  }, 30000);
});
只需点击一次即可正确地从控制台上反映的远程API更新数据。但当我检查我的浏览器时,它并没有更新


请对此问题提供帮助。

我不确定,但似乎当您的请求完成时,分配给路由处理程序回调函数的所有内存都被破坏,导致setInterval被删除


最好的方法是编写一个cron作业或计划任务,它将在特定的时间间隔或服务器的特定时间后命中您自己的一个api url,无论您喜欢哪个时间间隔。

我不确定,但似乎当您的请求完成时,分配给路由处理程序回调函数的所有内存都会被破坏要删除的设置间隔


最好的方法是编写一个cron作业或计划任务,在特定的时间间隔或服务器的特定时间后,该作业或任务将命中您自己的一个api url,无论您喜欢哪个时间间隔

我认为最好只在请求时获取结果,并将其缓存多长时间:

const express = require("express");
const app = express();
const request = require("request");
const url = "http://cricscore-api.appspot.com/csa";
const requestAsPromise = url =>
  new Promise(
    (resolve,reject)=>
      request(url, function(error, response, body) {
        (error)
          ? reject(error)
          : resolve(body)
      })
    )
const requestAndCache = ((cache,activePromises) => howLong => url => {
  if(activePromises.has(url)){
    return activePromises.get(url);
  }
  if(cache.has(url) && (cache.get(url).lastCached+howLong)<Date.now()){
    return Promise.resolve(cache.get(url).response);
  }else{
    cache.delete(url);
  }
  activePromises.set(
    "url",
    requestAsPromise(url).then(response=>{
      cache.set(url,{response,lastCached:Date.now()});
      activePromises.delete(url);
      return response;
    })
  );
  return activePromises.get(url);
})(new Map(),new Map());

const cacheForThirtySeconds = requestAndCache(30000);

app.get("/getTeam/:id", (req, res) => {
  const id = req.params.id;
  const purl = url + "?id=" + id;
  cacheForThirtySeconds(purl)
  .then(
    result=>{
      res.setHeader("content-type", "text/json");
      res.end(result);
    }
  ).catch(error=>{
    console.log("what to do when there is an error?");
    res.status(500).send('Something broke!')
  })
});
const express=require(“express”);
常量app=express();
常量请求=要求(“请求”);
常量url=”http://cricscore-api.appspot.com/csa";
const requestAsPromise=url=>
新承诺(
(解决、拒绝)=>
请求(url、函数(错误、响应、正文){
(错误)
?拒绝(错误)
:解析(正文)
})
)
const requestAndCache=((cache,activepromissions)=>howLong=>url=>{
if(activepromissions.has(url)){
返回ActivePromissions.get(url);
}
if(cache.has(url)&&(cache.get(url).lastCached+howLong){
set(url,{response,lastCached:Date.now()});
active承诺。删除(url);
返回响应;
})
);
返回ActivePromissions.get(url);
})(新地图(),新地图());
const cacheforthirtyses=requestAndCache(30000);
app.get(“/getTeam/:id)”,(req,res)=>{
const id=req.params.id;
const purl=url+“?id=“+id;
cacheforthirtyses(purl)
.那么(
结果=>{
res.setHeader(“内容类型”、“文本/json”);
目的(结果);
}
).catch(错误=>{
log(“出现错误时该怎么办?”);
res.status(500).send('Something break!')
})
});

我认为最好只在请求时获取结果,并将其缓存多长时间:

const express = require("express");
const app = express();
const request = require("request");
const url = "http://cricscore-api.appspot.com/csa";
const requestAsPromise = url =>
  new Promise(
    (resolve,reject)=>
      request(url, function(error, response, body) {
        (error)
          ? reject(error)
          : resolve(body)
      })
    )
const requestAndCache = ((cache,activePromises) => howLong => url => {
  if(activePromises.has(url)){
    return activePromises.get(url);
  }
  if(cache.has(url) && (cache.get(url).lastCached+howLong)<Date.now()){
    return Promise.resolve(cache.get(url).response);
  }else{
    cache.delete(url);
  }
  activePromises.set(
    "url",
    requestAsPromise(url).then(response=>{
      cache.set(url,{response,lastCached:Date.now()});
      activePromises.delete(url);
      return response;
    })
  );
  return activePromises.get(url);
})(new Map(),new Map());

const cacheForThirtySeconds = requestAndCache(30000);

app.get("/getTeam/:id", (req, res) => {
  const id = req.params.id;
  const purl = url + "?id=" + id;
  cacheForThirtySeconds(purl)
  .then(
    result=>{
      res.setHeader("content-type", "text/json");
      res.end(result);
    }
  ).catch(error=>{
    console.log("what to do when there is an error?");
    res.status(500).send('Something broke!')
  })
});
const express=require(“express”);
常量app=express();
常量请求=要求(“请求”);
常量url=”http://cricscore-api.appspot.com/csa";
const requestAsPromise=url=>
新承诺(
(解决、拒绝)=>
请求(url、函数(错误、响应、正文){
(错误)
?拒绝(错误)
:解析(正文)
})
)
const requestAndCache=((cache,activepromissions)=>howLong=>url=>{
if(activepromissions.has(url)){
返回ActivePromissions.get(url);
}
if(cache.has(url)&&(cache.get(url).lastCached+howLong){
set(url,{response,lastCached:Date.now()});
ActivePromissions.delete(url);
返回响应;
})
);
返回ActivePromissions.get(url);
})(新地图(),新地图());
const cacheforthirtyses=requestAndCache(30000);
app.get(“/getTeam/:id)”,(req,res)=>{
const id=req.params.id;
const purl=url+“?id=“+id;
cacheforthirtyses(purl)
.那么(
结果=>{
res.setHeader(“内容类型”、“文本/json”);
目的(结果);
}
).catch(错误=>{
log(“出现错误时该怎么办?”);
res.status(500).send('Something break!')
})
});

由于以下几个原因,此代码不起作用,第一个原因是您试图通过一个连接发送多个响应。调用
res.end()
后,响应将关闭,无法通过它发送更多内容

第二个原因是您将setInterval放在响应处理程序中,这意味着对该端点的每个请求都将创建一个新的计时器

您要做的是创建一种内存缓存,它使用ID作为缓存键,并保留一定的时间。通过这种方式,您可以将API的响应保存在服务器中,并将其作为响应发送,当您需要刷新数据时,您可以访问API

没有真正的理由自己构建,因为有很多社区建立的解决方案可供使用。例如这
apicache
Express中间件:

生成的代码可能如下所示:

const express = require("express");
const request = require("request");
const apicache = require("apicache");
const app = express();
const cache = apicache.middleware;
const url = "http://cricscore-api.appspot.com/csa";

app.get("/getTeam/:id", cache("30 seconds"), (req, res) => {
  const id = req.params.id;
  const purl = url + "?id=" + id;

  request(purl, (error, response, body) => {
    res.json(body);
  });
});

这段代码不起作用有几个原因,第一个原因是您试图通过一个连接发送多个响应。调用
res.end()
后,响应将关闭,无法通过它发送更多内容

第二个原因是您将setInterval放在响应处理程序中,这意味着对该端点的每个请求都将创建一个新的计时器

您要做的是创建一种内存缓存,它使用ID作为缓存键,并保留一定的时间。通过这种方式,您可以将API的响应保存在服务器中,并将其作为响应发送,当您需要刷新数据时,您可以访问API

没有真正的理由自己构建,因为有很多社区建立的解决方案可供使用。例如这
apicache
Express中间件:

生成的代码可能如下所示:

const express = require("express");
const request = require("request");
const apicache = require("apicache");
const app = express();
const cache = apicache.middleware;
const url = "http://cricscore-api.appspot.com/csa";

app.get("/getTeam/:id", cache("30 seconds"), (req, res) => {
  const id = req.params.id;
  const purl = url + "?id=" + id;

  request(purl, (error, response, body) => {
    res.json(body);
  });
});

从服务器或为be发送定期请求