Express.js GET请求不会在第一次调用时返回数据

时间:2018-06-04 21:49:10

标签: javascript node.js mongodb

我正在使用Node / Express / MongoDB构建应用程序(第一次使用所有这些),这将让我从数据库中提取数据并将其显示在Express页面上。这就是GET请求的样子:

var str = "";

app.route('/view-reports').get(function(req, res) {
  var cursor = collections.find({});

  cursor.each(function(err, item) {
    if (item != null) {
      console.log(str);
      str = str + "Substance: " + item.substance + "<br>";
    }
    if (err) {
      console.log(err);
    }
  });
  console.log(str);
  res.send(str);
  str = "";
});

我希望这会返回这样的内容:

  

物质:a

     

物质:b

     

物质:c

但是,初始请求根本不返回任何内容。第二个请求将返回上述内容。如果我将res.send(str)括在if条件中,则只有在第二次请求发出后才会加载。

2 个答案:

答案 0 :(得分:0)

cursor.each()是异步的。这意味着它有时会在您的res.send(str)之后运行,因此您会获得之前版本的str。您需要先收集所有数据,然后仅在拥有所有数据时发送响应。

如果您想要所有数据,那么您可以使用promises和.toArray()这样:

app.route('/view-reports').get(function(req, res) {
  collections.find({}).toArray().then(data => {
      let result = data.map(item => {
          return "Substance: " + item.substance + "<br>";
      }).join("");
      res.send(result);
  }).catch(err => {
      // database error
      console.log(err);
      res.sendStatus(500);
  });
});

注意:这也明智地删除了超出请求范围的str变量,因此当多个请求同时在飞行中时(从不同的用户)可能很容易导致并发错误

答案 1 :(得分:0)

专门为物质创建路由器并在app中使用它。您可以创建一个ul,而不是中断,处理应该在前端进行。分开你的顾虑。服务器不应该担心任何渲染等。每个进程有一个目的。

可以根据资源创建路由器。为物质,猫,狗创建路由器。每个路由器都有自己的get post delete和puts,允许您修改该资源。 axis(side=4,ylab="label")可以同时使用所有路由器。

app

&#13;
&#13;
app.use(catRouter);
app.use(mooseRouter);
app.use(platypusRouter);
&#13;
&#13;
&#13;

或者我们可以写:

&#13;
&#13;
const { Router } = require('express');
const createError = require('http-errors');
let substanceRouter = new Router();

function buildElement(arr)
{
  let start = '';
  arr.forEach(val => {
    if(!val) return;
    start += `Substance : ${val}<br>`;
  });
  return start;
}

subtanceRouter.get('/endpoint/whatever', function(req, res, next) {

  collectios.find({})
  
  .then(results => {
    if(!results) throw new Error('Resource Not Found');
    
    let output = buildElement(results);
    res.json(output);
    next();
  })
  
  .catch(err => next(createError(404, err.message)));
})

app.use(substanceRouter);
&#13;
&#13;
&#13;

但请注意,这会增加内存开销,生成一个全新的数组来存放结果,最坏的情况是消耗O(n)内存。