javascript - 您如何使用 Express 访问 Axios 响应?

标签 javascript node.js express axios

我刚开始使用 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;

服务器.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 ,讨论了为什么以及如何编写异步代码意味着您必须传播异步。

您现在编写的代码不会传播异步性。 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");
});

关于javascript - 您如何使用 Express 访问 Axios 响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51369468/

相关文章:

javascript - 增加延迟加载检测的视口(viewport)

JavaScript( typescript /Angular ): Shortest/Fastest method to set object keys/values based on previous logic?

css - 静态 css 不显示在 express jade 中

javascript - Cypress - 执行时出错 'cypress open'

javascript - 模块没有导出成员, 'Request'

javascript - 无法使用 jquery 找到元素

javascript - 如何防止 iFrame 中的 JavaScript 访问外部站点的属性,即使 iFrame 的内容来自同一来源?

javascript - Heroku Node.js Amazon S3 直接上传教程 - SignatureDoesNotMatch

javascript - Express 表单发布请求处理中间件返回 RangeError

node.js - NodeJS/Express 中使用 API 网关进行微服务 API 身份验证