簡體   English   中英

帶有 express、node、ejs 的 Axios 請求

[英]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);
  });

一些注意事項:

  1. 我將if語句中的返回值更改為單個值。 在使用 promise 和 async/await 時,您應該嘗試始終返回一個值(因為您只能解析/返回一個值)。
  2. 我看到很多以大寫字母開頭的函數。 JavaScript 中有一個約定,其中帶有大寫字母的函數是構造函數(意味着使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM