繁体   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