[英]Axios requests with express, node, ejs
我在一個使用 Express.js、node.js、Axios 和 ejs 的網站上工作。 我正在使用 Axios 對 Oracle SQL REST 服務進行 REST 調用。 我在使用 Promise 或 Async/Await 時遇到問題。 如果可能的話,我可以使用一些指導。
我有一個與 Oracle DB 交互的存儲庫層。 例如:
數據訪問.js
const axios = require('axios');
exports.IsManufacturerCategory = function (categoryId) {
axios.get(`DB ADDRESS ${categoryId}`)
.then(response => {
console.error('GET IsManufacturerCategory categoryId = ' + categoryId);
console.error('Response = ' + JSON.stringify(response.data));
return (response.data);
})
.catch(rej => {
console.error('ERROR IsManufacturerCategory categoryId = ' + categoryId);
console.error('ERR = \n' + rej.data);
return (rej.data);
});
}
在我的中間件中調用。 當我調用var isManufacturerCat = exports.IsManufacturerCategory(categoryId);
它是未定義的。 我正在嘗試使用從 Axios 調用中檢索到的數據將 ejs 視圖返回到我的路由器,如果需要,我可以提供。
類別.js
var isManufacturerCat = exports.IsManufacturerCategory(categoryId);
if (isManufacturerCat) {
var models = dataaccess.GetCategorySubCategories(categoryId);
return ("manufacturers", {
data: {
Canonical: cononical,
Category: category,
IsAManufacturerCategory: iAManufacturerCat,
Models: models
}
});
}
我對我的項目結構、Promises 的使用、Async/Await 等方面的任何建議持開放態度。
先感謝您。
編輯
在處理了一些給出的答案后,我取得了一些進展,但我在異步調用層方面遇到了問題。 我最終進入了一個需要await
呼叫的地方,但我處於我無法/不想這樣做的功能中(即我的路由器)。
indexMiddleware.js
exports.getRedirectURL = async function (fullOrigionalpath) {
if (fullOrigionalpath.split('.').length == 1 || fullOrigionalpath.indexOf(".aspx") != -1) {
if (fullOrigionalpath.indexOf(".aspx") != -1) {
//some string stuff to get url
}
else if (fullOrigionalpath.indexOf("/solutions/") != -1) {
if (!fullOrigionalpath.match("/solutions/$")) {
if (fullOrigionalpath.indexOf("/t-") != -1) {
//some stuff
}
else {
var solPart = fullOrigionalpath.split("/solutions/");
solPart = solPart.filter(function (e) { return e });
if (solPart.length > 0) {
var solParts = solPart[solPart.length - 1].split("/");
solParts = solParts.filter(function (e) { return e });
if (solParts.length == 1) {
waitForRespose = true;
const isASolutionCategory = await dataaccess.isASolutionCategory(solParts[0]); // returns void
if (isASolutionCategory != undefined && isASolutionCategory.length > 0 && isASolutionCategory[0].Count == 1) {
// set redirecturl
}
}
else {
redirecturl = "/solutions/solutiontemplate";
}
}
}
}
}
else if (URL STUFF) {
// finally if none of the above fit into url condition then verify current url with Category URL or product url into database and if that matches then redirect to proper internal URL
if (fullOrigionalpath.lastIndexOf('/') == (fullOrigionalpath.length - 1)) {
fullOrigionalpath = fullOrigionalpath.substring(0, fullOrigionalpath.lastIndexOf('/'));
}
waitForRespose = true;
const originalURL = await exports.getOriginalUrl(fullOrigionalpath); //returns string
redirecturl = originalURL;
return redirecturl;
}
}
if (!waitForRespose) {
return redirecturl;
}
}
exports.getOriginalUrl = async function (friendlyUrl) {
var originalUrl = '';
var urlParts = friendlyUrl.split('/');
urlParts = urlParts.filter(function (e) { return e });
if (urlParts.length > 0) {
var skuID = urlParts[urlParts.length - 1];
const parts = await dataaccess.getFriendlyUrlParts(skuID); //returns void
console.log("Inside GetOriginalUrl (index.js middleware) FriendlyUrlParts: " + parts);//undefined
if (parts != undefined && parts != null && parts.length > 0) {
//some stuff
}
else {
// verify whether it's category URL then return the category local URL
console.log('Getting CategoryLocalUrl');
const categoryLocalUrl = await dataaccess.getCategoryLocalUrl(friendlyUrl); // returns void
console.log('CategoryLocalUrl Gotten ' + JSON.stringify(categoryLocalUrl)); //undefined
if (categoryLocalUrl != undefined && categoryLocalUrl.length > 0) {
//set originalUrl
return originalUrl;
}
}
}
else { return ''; }
}
index.js 路由器
router.use(function (req, res, next) {
//bunch of stuff
index.getRedirectURL(url)
.then(res => {
req.url = res;
})
.catch(error => {
console.error(error);
})
.finally(final => {
next();
});
}
在await
之后,我在console.log
變得undefined
。 我不確定我在做什么,我猜。
讓我們從 dataaccess.js 開始。 基本上,您正在導出一個執行異步工作的函數,但該函數不是異步的。 大多數人都希望能夠使用 async/await,因此與其讓IsManufacturerCategory
接受回調函數,不如讓該函數返回一個承諾。 最簡單的方法是使函數成為異步函數。 異步函數返回比通過返回顯式承諾更容易解決/拒絕的承諾。 下面是如何重寫:
const axios = require('axios');
exports.IsManufacturerCategory = async function (categoryId) {
try {
const response = await axios.get(`DB ADDRESS ${categoryId}`);
console.log('GET IsManufacturerCategory categoryId = ' + categoryId);
console.log('Response = ' + JSON.stringify(response.data));
} catch (err) {
console.error('ERROR IsManufacturerCategory categoryId = ' + categoryId);
console.error('ERR = \n' + rej.data);
throw err;
}
}
請注意,我僅將console.error
用於錯誤。 因為您想記錄一些與錯誤相關的詳細信息,所以我使用了 try/catch 語句。 如果您不關心這樣做,該功能可以簡化為:
const axios = require('axios');
exports.IsManufacturerCategory = async function (categoryId) {
const response = await axios.get(`DB ADDRESS ${categoryId}`);
console.log('GET IsManufacturerCategory categoryId = ' + categoryId);
console.log('Response = ' + JSON.stringify(response.data));
}
這是因為異步函數會自動吞下錯誤並將它們視為拒絕 - 因此IsManufacturerCategory
返回的承諾將被拒絕。 類似地,當異步函數返回一個值時,promise 將使用返回的值進行解析。
轉到category.js...這看起來很奇怪,因為當我認為您的意思是從dataaccess模塊的導入訪問它時,您正在從該模塊的導出訪問IsManufacturerCategory
,對嗎?
在此函數中,您應該將任何異步工作放在異步函數中,以便您可以將 await 與返回承諾的函數一起使用。 下面是如何重寫它:
const dataaccess = require('dataccess.js');
async function validateManufacturerCat(categoryId) {
const isManufacturerCat = await dataaccess.IsManufacturerCategory(categoryId);
if (isManufacturerCat) {
const models = await dataaccess.GetCategorySubCategories(categoryId);
return ({
manufacturers: {
data: {
Canonical: cononical,
Category: category,
IsAManufacturerCategory: iAManufacturerCat,
Models: models
}
}
});
}
}
validateManufacturerCat(categoryId)
.then(res => {
console.log(res);
})
.catch(err => {
console.error(err);
});
一些注意事項:
if
語句中的返回值更改為單個值。 在使用 promise 和 async/await 時,您應該嘗試始終返回一個值(因為您只能解析/返回一個值)。new
關鍵字調用)。這是一個工作示例。 請注意,您需要一個回調函數來獲取可從承諾中獲得的數據
//client.js
const axios = require("axios")
exports.IsManufacturerCategory = function (url, callback) {
axios.get(url)
.then(response=>
{
callback(response.data);
})
.catch(error=>{
callback( error);
})
};
//app.js
const client = require('./client');
function process(data) {
console.log(data)
}
client.IsManufacturerCategory("http://localhost:3000/persons",process);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.