Javascript Axios与express、node、ejs的请求

Javascript Axios与express、node、ejs的请求,javascript,node.js,express,axios,Javascript,Node.js,Express,Axios,我正在一个使用Express.js、node.js、Axios和ejs的站点上工作。我正在使用Axios对Oracle SQL REST服务进行REST调用。我在使用承诺或异步/等待时遇到问题。如果可能的话,我需要一些指导 我有一个与OracleDB接口的存储库层。例如: dataaccess.js const axios = require('axios'); exports.IsManufacturerCategory = function (categoryId) { axios

我正在一个使用Express.js、node.js、Axios和ejs的站点上工作。我正在使用Axios对Oracle SQL REST服务进行REST调用。我在使用承诺或异步/等待时遇到问题。如果可能的话,我需要一些指导

我有一个与OracleDB接口的存储库层。例如:

dataaccess.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);
if (isManufacturerCat) {
    var models = dataaccess.GetCategorySubCategories(categoryId);
    return ("manufacturers", {
        data: {
            Canonical: cononical, 
            Category: category, 
            IsAManufacturerCategory: iAManufacturerCat, 
            Models: models
        }
    });
}
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 ''; }
}
这在我的中间件中被称为。当我调用
var isManufacturerCat=exports.ismanufacturercegory(categoryId)时它未定义。我试图使用从Axios调用中检索的数据将ejs视图返回到我的路由器,如果需要,我可以提供该视图

category.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);
if (isManufacturerCat) {
    var models = dataaccess.GetCategorySubCategories(categoryId);
    return ("manufacturers", {
        data: {
            Canonical: cononical, 
            Category: category, 
            IsAManufacturerCategory: iAManufacturerCat, 
            Models: models
        }
    });
}
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 ''; }
}
我愿意接受我的项目结构、承诺的使用、异步/等待等方面的任何建议

先谢谢你

编辑

在处理了给出的一些答案之后,我取得了一些进展,但是我在异步调用的层次上遇到了问题。我最终进入了一个需要等待呼叫的位置,但我所处的功能我无法/不想这样做(即我的路由器)

indexMiddleware.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);
if (isManufacturerCat) {
    var models = dataaccess.GetCategorySubCategories(categoryId);
    return ("manufacturers", {
        data: {
            Canonical: cononical, 
            Category: category, 
            IsAManufacturerCategory: iAManufacturerCat, 
            Models: models
        }
    });
}
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();
      });
}

我在我的
控制台中得到
未定义的
。在
等待
后记录
s。我想我不是很确定我在做什么。

这里是一个有效的例子。请注意,您需要一个回调函数来获取从promise中可用的数据

//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);

让我们从dataaccess.js开始。基本上,您正在导出一个执行异步工作的函数,但该函数不是异步的。大多数人希望能够利用async/Wait,因此与其让
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;
  }
}
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);
  });
请注意,我使用的是
控制台。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));
}
这是因为异步函数会自动吞下错误并将其视为拒绝,因此
ismanufacturercegory
返回的承诺将被拒绝。类似地,当异步函数返回值时,将使用返回的值解析承诺

转到category.js。。。这看起来很奇怪,因为您正在从该模块的导出访问
IsManufacturerCategory
,而我认为您的意思是从dataaccess模块的导入访问它,对吗

在这个函数中,您应该将任何异步工作放在一个异步函数中,这样您就可以将wait与返回承诺的函数一起使用。下面是如何重写的:

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;
  }
}
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
    语句中的返回值更改为单个值。在使用Promissions和async/await时,您应该尝试始终返回单个值(因为您只能解析/返回一个值)
  • 我看到很多以大写字母开头的函数。JavaScript中有一个约定,其中大写的函数是构造函数(意味着使用
    new
    关键字调用)
    那么我会删除
    var query=
    并使用then和catch吗?我已经更新了答案。我已经安排好了你的代码。另外,当我使用
    var isamufacturercategory=dataaccess.IsManufacturerCategory(categoryId)时,您还应该从函数返回数据,该函数仍然获得未定义的值我已经更新了代码。您需要一个回调函数来获取数据。我所做的示例按预期工作。好的,因此我更改了Axios调用,现在返回数据,但中间件在设置
    IsAManufacturerCategory
    变量之前没有等待调用返回。这就是我测试时导致未定义的原因。我能做些什么让它等一下吗?我感谢您的帮助,我已经考虑到这一点,并更新了我的代码。至于大写字母的函数,我继承了一个充满这些函数的代码库,以及回调地狱。我正试图把它转换成比回调更好的东西。我听到了。它可能是一个代码库,甚至在承诺成为一种东西之前,回调地狱更是一种常态——并不是每个人都知道异步库。现在不需要那么多了,但仍然很方便。如果您有更多问题,请告诉我!我将在哪里调用返回所有分层承诺结果的最终承诺?我的路由器的
    路由器需要这些信息。请使用
    功能或路由本身。出于某种原因,我觉得在路由器中呼唤承诺不是一个好习惯。这是一个公平的假设吗?当我更改代码时,我缺少的一件事是
    返回响应。
    exports.IsManufacturerCategory
    函数中的数据调用。我添加了这个,然后返回了数据。我想有时候你会忘记一些基本的东西。嗨,乔希,关于路由器,Express目前的设计不是为了满足承诺。Valeri Karpov在这里讨论了这一点:他使用包装器作为解决方法,但使用了一个简单的try/catch块。请参阅我编写的教程的这一部分:请注意,我正在捕获逻辑中出现的任何异常,并将错误传递给Express所期望的
    next