构造json响应。 NodeJS发送空响应

时间:2016-04-12 20:07:18

标签: javascript json node.js httpresponse

我有这个代码,我希望通过多次请求数据库来发送包含数据的响应。我不明白为什么它会发出空响应。

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;

2 个答案:

答案 0 :(得分:4)

问题在于Promise.then的异步性质。您看,在解决两个承诺之前,会调用JSON.stringifyres.end。要仅在获取所有数据时发送响应,您必须使用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()});
    });
});

答案 1 :(得分:1)

数据库调用是异步的。他们正在返回承诺并且您正在附加then函数,但是javascript的运行方式,函数调用getTagTypegetSpecie,然后使用res.end() 之前,promises解决并且db调用结束。

在回复回复之前,您需要确保等待所有承诺解决,这实质上要求嵌套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);
    });
});

此函数将立即返回,但在数据库调用完成之前不会调用res.end()

async/await添加到语言后,此代码会变得更清晰:)