简体   繁体   English

如何将两个呼叫的响应合并为一个响应?

[英]How to combine responses from two calls in one response?

I'm getting an empty response ( {} ), whereas my expected response is of format:我得到一个空响应 ( {} ),而我预期的响应格式为:

{
    locationResponse: "location foo",
    forecastResponse: "forecast bar"
}

In my index file I have:在我的索引文件中,我有:

const {getCity} = require('./routes/city');
const {getForecasts} = require('./routes/forecast');

app.get('/forecasts', function (req, res) {
    var location = getCity(req, res);
    var forecast = getForecasts(req, res);

    //these are logged as undefined
    console.log("Inside index.js");
    console.log(location);
    console.log(forecast);
    res.send({locationResponse: location, forecastResponse: forecast});
});

Inside forecast file I have the following, and a similar one is in city file:在预测文件中,我有以下内容,城市文件中有一个类似的:

module.exports = {
    getForecasts: (req, res) => {
       var result = //mySQL DB calls and processing
       console.log("Inside getForecasts");
       console.log(result); //actual result printed
       return "Forecast";
    }

UPDATE : So I added some logs right before each call's return statements and figured out that the logs are printed in the following order, which means, it is not working as expected because I have not considered the fact that they are asynchronous calls.更新:所以我在每次调用的返回语句之前添加了一些日志,并发现日志按以下顺序打印,这意味着它没有按预期工作,因为我没有考虑到它们是异步调用的事实。

Inside index.js
undefined
undefined
Inside getForecasts
{result}

The problem here is that in your ./routes/forecast/ getForecasts method, you're telling the response to send, with the data "Forecast".这里的问题是,在你的./routes/forecast/ getForecasts 方法中,你告诉响应发送,数据“预测”。 You should only ever use res.send once per request, as this will resolve the response and return to the client.每个请求只应使用 res.send 一次,因为这将解析响应并返回给客户端。

Instead, your getForecasts method should just return whatever data you need, and your index file should handle the response.相反,您的 getForecasts 方法应该只返回您需要的任何数据,并且您的索引文件应该处理响应。 If you need getForecasts to handle a response too, perhaps because you're sending requests directly to a forecasts endpoint that doesn't require location data, then you can refactor your code so that both index and forecasts make a call to get the data you need.如果您也需要 getForecasts 来处理响应,也许是因为您将请求直接发送到不需要位置数据的预测端点,那么您可以重构您的代码,以便索引和预测都调用以获取您的数据需要。 For example:例如:

/* index.js */
const {getCity} = require('./data/city');
const {getForecasts} = require('./data/forecast');

app.get('/forecasts', function (req, res) {
    var location = getCity();
    var forecast = getForecasts();
    res.send({locationResponse: location, forecastResponse: forecast});
});

/* data/forecast.js */
module.exports = {
    getForecasts: () => {
        return "Forecast";
    }
};

/* data/city.js */
module.exports = {
    getCity: () => {
        return "City";
    }
};

Then you can also have:然后你还可以有:

/* routes/forecast.js */
const {getForecasts} = require('../data/forecast');
module.exports = {
    getForecasts: (req, res) => {
        res.send(getForecasts());
    }
};

The above may be overcomplicating things, but I made the assumption that if you're using a routes directory, you probably want route handlers to be stored there.上面的内容可能过于复杂,但我假设如果您使用routes目录,您可能希望将路由处理程序存储在那里。 Hope this helps.希望这可以帮助。

Seems both of your getCity() and getForecasts() functions are async.似乎您的 getCity() 和 getForecasts() 函数都是异步的。 These asynchronous functions return a promise rather actual response.这些异步函数返回一个承诺而不是实际的响应。

So you can use simple asysn/await or Promise.all in JS to solve the issue.所以你可以使用简单的asysn/await或者 JS 中的Promise.all来解决这个问题。

Option 1: Use await for the promise to resolve before logging the message to the console:选项 1:在将消息记录到控制台之前,使用await作为要解决的承诺:

app.get('/forecasts', async function (req, res) {
    var location = await getCity(req, res);
    var forecast = await getForecasts(req, res);

    //these are logged as undefined
    console.log("Inside index.js");
    console.log(location);
    console.log(forecast);
    res.send({locationResponse: location, forecastResponse: forecast});
});

Option 2: Use Promise.all() to wait for all the promises to have fulfilled.选项 2:使用Promise.all()等待所有Promise.all()完成。

app.get('/forecasts', function (req, res) {
    var list = await Promise.all([getCity(req, res), getForecasts(req, res)]);

    //these are logged as undefined
    console.log("Inside index.js");
    console.log(list[0]);
    console.log(list[1]);
    res.send({locationResponse: list[0], forecastResponse: list[1]});
});

You can make use of async/await syntax.您可以使用async/await语法。

app.get('/forecasts', async function (req, res) {
    var location = await getCity(req, res);
    var forecast = await getForecasts(req, res);

    //these are logged as undefined
    console.log("Inside index.js");
    console.log(location);
    console.log(forecast);
    res.send({locationResponse: location, forecastResponse: forecast});
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM