Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript mySQL导致节点中出现异步/等待问题_Javascript_Node.js_Asynchronous_Promise_Async Await - Fatal编程技术网

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

Javascript mySQL导致节点中出现异步/等待问题,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,我有以下代码,这是通过Express进行的API调用。我需要返回一个引号数组,以及一个与这些引号关联的部分数组。为此,我使用async/await,它在我的quotes变量中正常工作,但在parts变量中得到一个空数组 我相信这与部分结果是挂起的承诺有关,因为当我在循环中记录我的结果时,我得到了适当的值 我怀疑我一定是误解了async/await是如何工作的,或者promises/Promise.all是如何工作的 任何帮助我理解为什么我没有得到履行承诺的结果是感激的 router.get('/

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

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

我怀疑我一定是误解了async/await是如何工作的,或者promises/Promise.all是如何工作的

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

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; 
}

获取未定义值数组的原因是返回的是
quotePartsResult
,而不是推送值的
quoteParts
。由于您在
quoteResult
上运行.map,并且没有在map函数中返回任何内容,因此它将解析为未定义

为了更好地理解,我想重构您的代码。在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;

正如有人在评论中提到的那样,我缺少的主要事情是在我的第二次连接周围有一个新的承诺包装器。我还需要一个承诺。在第二个函数getQuoteParts中。下面是最终代码的样子:

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);
  
}
我在这里写了一篇文章概述了它的工作原理:

你说得对–我尝试了两种方法,一种是从循环内返回,另一种是推到阵列,我想我忘记在这里更改了。但是,遗憾的是,当我将其更改为quoteParts时,仍然会得到一个空数组。@AmyMurphy我已经更新了我的答案。你能试试吗?在
getQuoteParts
中,你错过了
连接周围的
新承诺。如果你把它作为回答,我很乐意接受。