当前位置: 首页 > 知识库问答 >
问题:

mySQL导致节点中出现异步/等待问题

顾骏祥
2023-03-14

我有以下代码,这是通过Express调用的API。我需要返回一个引号数组,以及与这些引号相关联的部分数组。为此,我使用async/wait,它在我的引号变量中正常工作,但我在部件变量中得到一个空数组。

我相信这与部分结果是挂起的promise有关,因为当我在循环中记录我的结果时,我得到了适当的值。

我怀疑我一定是误解了async/await是如何工作的,或者promises/Promise是如何工作的。一切顺利。

任何帮助我理解为什么我没有得到履行promise的结果是感激的!

router.get('/:pagenum/:dealerno/:modelyear/', async (req, res) => {
  let quotes = await getQuotes(
    req.params.pagenum,
    req.params.dealerno,
    req.params.modelyear
  );

  console.log('MY QUOTES:');
  console.log(quotes); //This returns an array of my quotes, as expected

  let parts = await getQuoteParts(quotes);

  console.log('MY PARTS:');
  console.log(parts); //This returns an array of undefined values
});

function getQuotes(pagenum, dealerno, modelyear) {
  // return new Promise(function (resolve, reject) {
  var q_quote =
    "SELECT quote.id, DATE_FORMAT(quote.timestamp, '%b %d, %Y') AS timestamp, quote.quotenum, quote.quotetype, quote.configtype, quote.sid, quote.tractortype, customer.cus_id, customer.customername, parts.partno, units.type AS fmtype, combos.type AS mmtype FROM GH_savedquoteinfo AS quote JOIN GH_internal_customers AS customer ON quote.cusid=customer.cus_id JOIN GH_savedquoteparts AS parts ON (quote.quotenum = parts.quotenum AND parts.type='unit') LEFT JOIN " +
    modelyear +
    "_fm_units AS units ON (parts.partno = units.model_no AND quote.tractortype='FM') LEFT JOIN " +
    modelyear +
    "_mm_combos AS combos ON (parts.partno = combos.model_no AND quote.tractortype='MM') WHERE quote.dealerno=? AND quote.modelyear=? AND quote.quotetype!='multi' ORDER BY quote.quotenum LIMIT 7 OFFSET 0;";

  let resultHolder = [];

  return new Promise((resolve, reject) => {
    connection.query(q_quote, [dealerno, modelyear], function (
      err_quote,
      result_quote
    ) {
      if (err_quote) {
        console.log('error');
      } else {
        try {
          resultHolder.push(result_quote);
        } catch (e) {
          console.log('error');
        } finally {
          resolve(resultHolder);
        }
      }
    });
  });
}

async function getQuoteParts(quoteResult) {
  let quoteParts = [];
  let quotePartsResult = await Promise.all(
    quoteResult[0].map(async (quote, index) => {
      var q_parts =
        "SELECT * FROM GH_savedquoteparts WHERE quotenum=? AND (type='' OR type='pvcomplete') ORDER BY id";

      connection.query(q_parts, [quote.quotenum], function (
        err_parts,
        result_parts
      ) {
        if (err_parts) {
          console.log('error in parts' + err.message);
        } else {
          console.log(result_parts); //This returns an array of my parts
          quoteParts.push(result_parts);
        }
      });
    })
  );

  return quoteParts; 
}

共有2个答案

西门京
2023-03-14

正如评论中有人提到的,我缺少的主要东西是我第二个连接周围的一个新的promise包装。我还需要第二个函数getQuoteParts中的Promise.all。以下是最终代码的样子:

router.get('/:pagenum/:dealerno/:modelyear/', async (req, res) => {
  //QUOTES ARRAY
  const quotes = await getQuotes(
    req.params.pagenum,
    req.params.dealerno,
    req.params.modelyear
  );

  const parts = await getQuoteParts(quotes);

  const details = await getPartDescrips(parts, quotes);

  Promise.all([quotes, parts, details]).then((results) => {
    res.send(results);
  });
});

function getQuotes(pagenum, dealerno, modelyear) {
  // return new Promise(function (resolve, reject) {
  const qQuote =
    "SELECT quote.id, DATE_FORMAT(quote.timestamp, '%b %d, %Y') AS timestamp, quote.quotenum, quote.quotetype, quote.configtype, quote.sid, quote.tractortype, customer.cus_id, customer.customername, parts.partno, units.type AS fmtype, combos.type AS mmtype FROM GH_savedquoteinfo AS quote JOIN GH_internal_customers AS customer ON quote.cusid=customer.cus_id JOIN GH_savedquoteparts AS parts ON (quote.quotenum = parts.quotenum AND parts.type='unit') LEFT JOIN " +
    modelyear +
    "_fm_units AS units ON (parts.partno = units.model_no AND quote.tractortype='FM') LEFT JOIN " +
    modelyear +
    "_mm_combos AS combos ON (parts.partno = combos.model_no AND quote.tractortype='MM') WHERE quote.dealerno=? AND quote.modelyear=? AND quote.quotetype!='multi' ORDER BY quote.quotenum DESC LIMIT 7 OFFSET 0;";

  let resultHolder = [];

  return new Promise((resolve, reject) => {
    connection.query(qQuote, [dealerno, modelyear], function (
      errQuote,
      resultQuote
    ) {
      if (errQuote) {
        console.log(errQuote.message);
      } else {
        try {
          resolve(resultQuote);
        } catch (e) {
          console.log(e.message);
        }
      }
    });
  });
}

function getQuoteParts(quoteResult) {
  var partResults = quoteResult.map((quote, index) => {
    return new Promise((resolve, reject) => {
      const qParts =
        "SELECT * FROM GH_savedquoteparts WHERE quotenum=? AND (type='' OR type='pvcomplete') ORDER BY type='pvcomplete', type='', id";
      // new Promise((resolve, reject) => {
      connection.query(qParts, [quote.quotenum], function (
        errParts,
        resultParts
      ) {
        if (errParts) {
          console.log('error in PARTS');
        } else {
          resolve(resultParts);
        }
      });
    });
  });

  return Promise.all(partResults);
  
}

我在这里写了一篇文章概述了它的工作原理:https://medium.com/@Amymurphy40966/node-mysql-chained-promises-vs-async-await-9d0c8e8f5ee1

曾枫
2023-03-14

获取未定义值数组的原因是返回的是quotePartsResult,而不是推送值的quoteParts。因为你在经营一家公司。映射到quoteResult并且在映射函数中不返回任何内容,它将解析为未定义。

为了更好地理解,我想重构您的代码。你的promise中应该有一系列的promise。all()调用

比如:

const promises = qouteResult.map(async (quote) => {
  // Your query calls. You can also promisify the callbacks in here using 
  util.promisify()
});

OR

const promises = qouteResult.map(qoute => {

return new Promise((resolve,reject) => {
  // Your query calls.
  if(success) {
    resolve()
  } else {
    reject()
  }
});
});

const result = await Promise.all(promises);
return result;
 类似资料:
  • 问题内容: 我对节点还很陌生,我刚刚了解了javascript中提供的async和await函数。我正在尝试在下面随附的代码段中实现此方法。以我的理解,数据库响应应该首先打印到控制台,然后“完成”,但是我无法使其正常工作。任何帮助将不胜感激。 也请尝试说明您所做的修复操作,因为我想了解我做错了什么。 问题答案: 您的函数中没有语句。 通常,这将导致函数返回,但是由于您声明了它,因此它导致其返回 立

  • 问题内容: 我认为节点7.4支持异步/等待,但是此示例不起作用: 结果是: 如何在节点7.4上使用异步/等待? 问题答案: 是的,Node.js v7支持async-await,但将其锁定在标志后面。尚未准备就绪的功能不在此标记后面。 要在Node.js v7中使用async-await,只需使用此标志运行Node服务- async-await的正式发行版预定于4月启动的Node.js v8。 您

  • 我以为async/wait在节点7.4中得到了支持,但是这个例子不起作用: 结果: 如何在node 7.4中使用async/await?

  • 我遇到了一些使用c#的/关键字进行异步编程的最佳实践(我是c# 5.0的新手)。 给出的建议之一如下: 稳定性:了解您的同步上下文 ...一些同步上下文是不可重入的和单线程的。这意味着在给定时间只能在上下文中执行一个工作单元。这方面的一个例子是Windows UI线程或ASP.NET请求上下文。在这些单线程同步上下文中,很容易死锁。如果您从单线程上下文中生成一个任务,然后在上下文中等待该任务,您的

  • 问题内容: 我有一个使用一些异步功能的节点应用程序。 在继续进行其余的应用程序流程之前,我该如何等待异步功能完成? 下面有一个简单的示例。 在示例中,要返回的元素“ ”必须为5而不是1。如果应用程序不等待异步功能,则等于1。 谢谢 问题答案: 使用回调机制: 使用异步等待

  • 我试图在react/electron项目中使用async/await,但它不起作用。我想要的是获取docker容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)