如何使用 Express 访问 Axios 响应?

Posted

技术标签:

【中文标题】如何使用 Express 访问 Axios 响应?【英文标题】:How do you access Axios response with Express? 【发布时间】:2018-12-24 10:51:35 【问题描述】:

我刚开始使用 Express,目前不知道如何使用路由参数发出 Axios 请求并根据请求返回的内容更改一些本地变量。这是我目前所拥有的:

helpers.js

const axios = require('axios');
const 
  titleSuffix,
  organizationPath,
  varietyPath
 = require('./constants');

let organizationData = ;
let varietyData = ;

const Helpers = 

  fetchOrganization: (organizationID) => 
    axios.get(organizationPath + organizationID)
      .then( (response) => 
        //console.log(response);
        organizationData = response.data.data;
      )
      .catch( (error) => 
        //console.log(error);
      );
      return organizationData;
  ,

  fetchVariety: (varietyID) => 
    axios.get(varietyPath + varietyID)
      .then( (response) => 
        //console.log(response);
        varietyData = response.data.data;
      )
      .catch( (error) => 
        //console.log(error);
      );
      return varietyData;
  ,

  setOrgOpenGraphTags: (growerHash, res) => 
    Helpers.fetchOrganization(growerHash);
    res.locals.meta.og.title = organizationData.name + titleSuffix;
    console.log('Org = ' + organizationData.name);
  ,

  setVarOpenGraphTags: (contextualId, res) => 
    Helpers.fetchVariety(contextualId);
    res.locals.meta.og.title = varietyData.name + titleSuffix;
    console.log('Var = ' + varietyData.name);
  

;

module.exports = Helpers;

server.js

// Express
const express = require('express');
const app = express();

// Helpers
const 
  setOrgOpenGraphTags,
  setVarOpenGraphTags
 = require('./helpers');

// Organization
app.get(['/org/:growerHash/*', '/_org/:growerHash/*'], (req, res) => 
  setOrgOpenGraphTags(req.params.growerHash, res);
  res.render('org');
);

我相当肯定我遗漏了一些小东西,但根据 Axios 的响应似乎无法更改以下本地内容:

res.locals.meta.og.title

根据我目前的情况,如何正确访问 Express 中 Axios 的响应并更改本地人?我真的需要一个基于我提供的代码的答案。目前在我的开发环境中,该请求有效,但在生产中它返回“未定义”。提前非常感谢。

【问题讨论】:

Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference的可能重复 fetchOrganization 是异步的,您无需等待。 我的问题非常具体,您的笼统回答对我没有帮助,也不是重复的。感谢您也对我的彻底问题投了反对票@zero298 @zero298 在这里为您提供服务。他的回答给了你你需要的一切,所以我建议你仔细阅读然后接受它——你不太可能得到更多的答案。 【参考方案1】:

我链接的副本Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference 讨论了为什么以及如何编写异步代码意味着您必须以异步方式传播。

您现在编写的代码不会传播异步性。 axios.get() 返回 Promise。除非依赖于 Promise 解析的值的所有内容实际上都在等待 Promise 链解析,否则您不会得到您所期望的。

考虑一下我在下面评论过的代码:

const axios = require('axios');

const Helpers = 
  fetchOrganization: (organizationID) => 
    // axios.get() will return a Promise
    // You have to wait for the Promise to finish before
    // you can use any data that it produces
    // You must propogate the Proise of data up

    // You should return axios.get(...)
    axios.get(organizationPath + organizationID)
      .then((response) => 
        //console.log(response);
        organizationData = response.data.data;
      )
      .catch((error) => 
        //console.log(error);
      );
    // This won't be populated by the time you try to use it
    return organizationData;

    // Instead do
    return axios
      .get(organizationPath + organizationID)
      .then(response => 
        const organizationData = response.data.data;
        return organizationData
      )
      .catch(err => console.error(err));

    // Better yet, do
    /*
    return axios.get(organizationPath + organizationID)
        .then(res => response.data.data) // Return is implied
        .catch(err => console.error(err));
    */
  ,

  setOrgOpenGraphTags: (growerHash, res) => 
    // Nothing is coming out of this function and you aren't waiting on it
    Helpers.fetchOrganization(growerHash);

    // Instead do
    return Helpers.fetchOrganization(growerHash)
      .then(org => 
        return org.name + titleSuffix;
      );

    //res.locals.meta.og.title = organizationData.name + titleSuffix;
    //console.log('Org = ' + organizationData.name);
  


// Organization
app.get(['/org/:growerHash/*', '/_org/:growerHash/*'], (req, res) => 
  // Below, you are starting the async process
  // but you don't wait for the async to finish
  // you just immediately res.render()
  setOrgOpenGraphTags(req.params.growerHash, res);
  res.render('org');

  // Instead
  setOrgOpenGraphTags(req.params.growerHash, res)
    .then(orgTitle => 
      res.locals.meta.og.title = orgTitle;
      res.render('org');
    );
);

考虑到这一点,让我们考虑一个代码的提炼版本,它将等待Promise 链解析:

// Let's boil your app down to it's core
const SOME_SUFFIX = "foobar";

// fetchOrganization
function getSomeData(id) 
  return axios
    .get(`http://www.example.com/things/$id`)
    .then(thatThing => thatThing.nested.property.i.want)
    .catch(err => console.error(err));


// setOrgOpenGraphTags
function calculateDerivedData(id) 
  return getSomeData(id)
    .then(thatThingsProperty => `$thatThingsProperty-$SOME_SUFFIX`)


// Route
app.get("/some/endpoint/:id", (req, res) => 
  calculateDerivedData(req.params.id)
    .then(thatDerivedDataWeNeed => 
      res.locals.whatever = thatDerivedDataWeNeed;
      res.render("someTemplate");
    )
);

如果你想写一些看起来可以说更干净的东西,你也可以考虑async/await

// Let's boil your app down to it's core
const SOME_SUFFIX = "foobar";

// fetchOrganization
async function getSomeData(id) 
    try 
        const thatThing = await axios.get(`http://www.example.com/things/$id`);
        return thatThing.nested.property.i.want;
     catch(err)
        console.error(err);
    


// setOrgOpenGraphTags
async function calculateDerivedData(id) 
    const thatThingsProperty = await getSomeData(id);
    return `$thatThingsProperty-$SOME_SUFFIX`;


// Route
app.get("/some/endpoint/:id", async function(req, res) => 
  res.locals.whatever = await calculateDerivedData(req.params.id);
  res.render("someTemplate");
);

【讨论】:

嘿@zero298,感谢您花时间深入回答这个问题。这肯定有帮助,但我注意到在生产中返回了“绑定 consoleCall”。任何想法为什么会这样?我以前从未遇到过。 @nunya 它在哪里返回?

以上是关于如何使用 Express 访问 Axios 响应?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Node、Express、Axios 在 ReactJS 前端设置带有 JWT 令牌的 cookie

如何将 map() 与来自 axios 响应的数据一起使用?

Express 服务器和 Axios CORS Preflight 响应不成功

在 Heroku 部署中响应对 Express API 的 axios 调用

如何从返回 axios 的响应对象访问 JWT 令牌值?

在 axios 发布请求后使用 express 进行重定向