无法在Node.js中启动后台进程

时间:2019-01-17 21:11:51

标签: javascript node.js reactjs express asynchronous

我有一个带有以下代码的node.js / express设置。客户端代码是使用React构建的。他们能够使用从1到他们想要的取值来查询X个玩家。该查询将发送到我的Express服务器,该服务器将请求发送到Riot Games公共api。我遇到的问题是,如果查询太大,则获取超时。

有人给我一个想法,让初始POST请求返回一个“ id”,然后在后台运行实际的查询。然后让客户端的浏览器定期检查查询是否已完成GET请求。

我在React componentDidMount()中调用初始POST,然后在 componentDidUpdate()中发送GET请求。我认为我搞不清的地方是发送get请求时以及启动后台进程的方式。我将查询的结果推送到allResults [0]数组。 playerRequest 是一个异步功能。

希望我已经很好地解释了...不确定要怎么做。

src / server / index.js

var playerSearch = require('./playerSearch.js');
const express = require('express');
const bodyParser = require('body-parser');
const uuidv1 = require('uuid/v1');

const app = express();
app.use(express.static('dist'));
app.use(bodyParser.json());
app.use(express.json());

const port = process.env.PORT || 8080;
app.listen(port, () => console.log('Listening on port ' + port + '!'));

var allResults = [];

//Beginning of all methods
app.get('/api/getUsername', (req, res) => res.send({ username: 'Summoner' }));

app.post('/api/champstats/initiatePlayerSearch', async function(req, res){
  var searchID = uuidv1();
  allResults.push(await playerSearch(req, searchID));
  console.log('Search ID: ' + searchID);
  return res.send({searchID: searchID});
});

app.get('/api/champstats/playerSearch/:searchId', async function(req, res){
  const result = await allResults.filter(x => x.requestID === req.params.searchID);
  return res.send({stats: result[0].stats});
});

1 个答案:

答案 0 :(得分:0)

等待异步结果端点中的promise,但如果尚未获取结果,也会超时:

var playerSearch = require('./playerSearch.js');
const express = require('express');
const bodyParser = require('body-parser');
const uuidv1 = require('uuid/v1');

const {promisify} = require('util');

const app = express();
app.use(express.static('dist'));
app.use(bodyParser.json());
app.use(express.json());

const port = process.env.PORT || 8080;
app.listen(port, () => console.log('Listening on port ' + port + '!'));

var allResults = {};

const timeout = promisify(setTimeout);

//Beginning of all methods
app.get('/api/getUsername', (req, res) => res.send({ username: 'Summoner' }));

app.post('/api/champstats/initiatePlayerSearch', async function(req, res){
  var searchID = uuidv1();
  allResults[searchID] = playerSearch(req, searchID);
  console.log('Search ID: ' + searchID);
  return res.send({searchID: searchID});
});

app.get('/api/champstats/playerSearch/:searchId', async function(req, res){
  const searchResult = allResults[req.params.searchID];
  const result = await Promise.race([ // return the first result you get
    timeout(100).then(async ()=>null), // wait for 100ms then return null.
    searchResult # if the search result returns before 100ms, use that as the result
    ]);
  if (result != null){
    return res.send({stats: result[0].stats});
  } else {
    // return an error message so you can try again later
  }
});

如果要尝试使用异步等待,可以使用几种方式来实现此模式,而不是使用.then。不过要注意的是,超时的任何回调都可能不应响应该请求,因为如果另一个诺言首先返回,则该请求不会被取消。传递给.race的所有诺言最终都将完成,因此,如果您在res上调用方法,请记住这一点。 .race不会取消未完成的承诺。