正在构建 json 响应。 NodeJS 发送空响应
Constructing json response. NodeJS send empty response
我有这段代码,我想发送一个响应,其中包含我通过多次请求数据库获得的数据。我不明白为什么它会发送一个空响应。
var express = require('express'),
router = express.Router(),
database = require('../database');
router.get('/', function(req, res, next){
res.writeHead(200, {"Content-Type": "application/json"});
var ttt;
var yyy;
database.getTagType().then(function(data) {
ttt = "pfff";
});
database.getSpecie().then(function(data) {
yyy = "akkhhh";
});
var json = JSON.stringify({
anObject: ttt,
anArray: yyy,
});
res.end(json);
});
module.exports = router;
问题出在 Promise.then
的异步性质上。你看, JSON.stringify
和 res.end
在两个 promise 都被 resolve 之前被调用了。要仅在获取所有数据时发送响应,您必须使用 Promise.all
方法。
这是一个如何完成的例子:
router.get('/', function(req, res, next){
var promises = [];
promises.push(database.getTagType().then(function(data){
return "pfff";
}));
promises.push(database.getSpecie().then(function(data) {
return "akkhhh";
}));
Promise.all(promises).then(function(values) {
// Actually, express can stringify response for us. Also it adds
// correct "Content-Type" header.
res.json({
anObject: values[0],
anArray: values[1]
});
}).catch(function(error) {
// Something went wrong. Let the error middleware deal with the problem.
next(error);
// Instead we can just send an error response, like so:
// res.status(500).json({error: error.toString()});
});
});
数据库调用是异步的。它们是 returning promises 并且您正在附加 then
函数,但是 javascript 运行的方式是调用 getTagType
和 getSpecie
然后发送res.end()
在 承诺解决之前响应,数据库调用结束。
您需要确保在回复响应之前等待所有承诺解决,这实际上需要嵌套 then()
函数。
像这样:
router.get('/', function(req, res, next){
res.writeHead(200, {"Content-Type": "application/json"});
var tag = database.getTagType();
// `tag` is now a promise
var specie = database.getSpecie();
// `specie` is a promise
Promise.all([tag, specie]).then(function(values) {
// this code is executed once both promises have resolved, the response has come back from the database
var json = JSON.stringify({
tag: values[0],
specie: values[1]
)};
res.end(json);
});
});
此函数将立即 return,但在数据库调用完成之前不会调用 res.end()
。
一旦 async/await
添加到语言中,此代码就会变得更清晰 :)
我有这段代码,我想发送一个响应,其中包含我通过多次请求数据库获得的数据。我不明白为什么它会发送一个空响应。
var express = require('express'),
router = express.Router(),
database = require('../database');
router.get('/', function(req, res, next){
res.writeHead(200, {"Content-Type": "application/json"});
var ttt;
var yyy;
database.getTagType().then(function(data) {
ttt = "pfff";
});
database.getSpecie().then(function(data) {
yyy = "akkhhh";
});
var json = JSON.stringify({
anObject: ttt,
anArray: yyy,
});
res.end(json);
});
module.exports = router;
问题出在 Promise.then
的异步性质上。你看, JSON.stringify
和 res.end
在两个 promise 都被 resolve 之前被调用了。要仅在获取所有数据时发送响应,您必须使用 Promise.all
方法。
这是一个如何完成的例子:
router.get('/', function(req, res, next){
var promises = [];
promises.push(database.getTagType().then(function(data){
return "pfff";
}));
promises.push(database.getSpecie().then(function(data) {
return "akkhhh";
}));
Promise.all(promises).then(function(values) {
// Actually, express can stringify response for us. Also it adds
// correct "Content-Type" header.
res.json({
anObject: values[0],
anArray: values[1]
});
}).catch(function(error) {
// Something went wrong. Let the error middleware deal with the problem.
next(error);
// Instead we can just send an error response, like so:
// res.status(500).json({error: error.toString()});
});
});
数据库调用是异步的。它们是 returning promises 并且您正在附加 then
函数,但是 javascript 运行的方式是调用 getTagType
和 getSpecie
然后发送res.end()
在 承诺解决之前响应,数据库调用结束。
您需要确保在回复响应之前等待所有承诺解决,这实际上需要嵌套 then()
函数。
像这样:
router.get('/', function(req, res, next){
res.writeHead(200, {"Content-Type": "application/json"});
var tag = database.getTagType();
// `tag` is now a promise
var specie = database.getSpecie();
// `specie` is a promise
Promise.all([tag, specie]).then(function(values) {
// this code is executed once both promises have resolved, the response has come back from the database
var json = JSON.stringify({
tag: values[0],
specie: values[1]
)};
res.end(json);
});
});
此函数将立即 return,但在数据库调用完成之前不会调用 res.end()
。
一旦 async/await
添加到语言中,此代码就会变得更清晰 :)