我正在使用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条件中,则只有在第二次请求发出后才会加载。
答案 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
app.use(catRouter);
app.use(mooseRouter);
app.use(platypusRouter);
&#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;
但请注意,这会增加内存开销,生成一个全新的数组来存放结果,最坏的情况是消耗O(n)内存。