首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Express.js GET请求在第一次调用时未返回数据

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

Stack Overflow用户
提问于 2018-06-05 05:49:10
回答 2查看 1.1K关注 0票数 0

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

代码语言:javascript
复制
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条件中,那么在发出第二个请求之前,它根本不会加载。

EN

回答 2

Stack Overflow用户

发布于 2018-06-05 06:02:13

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

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

代码语言:javascript
复制
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变量,该变量超出了请求的范围,因此当多个请求同时运行(来自不同用户)时,很容易导致并发错误。

票数 0
EN

Stack Overflow用户

发布于 2018-06-05 07:11:40

创建一个专门针对物质的路由器,并在app中使用它。您可以创建一个ul,而不是中断,而且,处理应该在前端进行。分离你们的关注点。服务器不应该担心任何渲染等问题。每个进程只有一个目的。

可以为每个资源创建路由器。为猫和狗创建一个物质路由器。每个单独的路由器都有自己的get、post、delete和puts,允许您修改该资源。app可以同时使用所有路由器。

app.use(catRouter); app.use(mooseRouter); app.use(platypusRouter);

代码语言:javascript
复制
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);

或者,我们可以这样写:

代码语言:javascript
复制
let output = results
            .filter(sub => !!sub)
            .join('<br>');
res.json(output);

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50689235

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档