nun*_*nya 1 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;
Run Code Online (Sandbox Code Playgroud)
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');
});
Run Code Online (Sandbox Code Playgroud)
我很确定我错过了一些小东西,但似乎无法根据Axios的响应得到以下本地更改:
res.locals.meta.og.title
Run Code Online (Sandbox Code Playgroud)
基于我到目前为止如何正确访问Express中的Axios响应并更改本地?我真的需要一个基于我提供的代码的答案.目前在我的开发环境中,请求有效但在生产中它返回"未定义".非常感谢提前.
我链接的副本,为什么我的变量在我修改函数内部后没有改变?- 异步代码引用,讨论为什么以及如何编写异步代码意味着必须传播异步.
正如现在所写的那样,您的代码不会传播异步性. 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');
});
});
Run Code Online (Sandbox Code Playgroud)
在考虑之后,让我们考虑一下等待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");
})
});
Run Code Online (Sandbox Code Playgroud)
如果你想写一些看起来更清洁的东西,你也可以考虑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");
});
Run Code Online (Sandbox Code Playgroud)