Javascript mySQL导致节点中出现异步/等待问题
我有以下代码,这是通过Express进行的API调用。我需要返回一个引号数组,以及一个与这些引号关联的部分数组。为此,我使用async/await,它在我的quotes变量中正常工作,但在parts变量中得到一个空数组 我相信这与部分结果是挂起的承诺有关,因为当我在循环中记录我的结果时,我得到了适当的值 我怀疑我一定是误解了async/await是如何工作的,或者promises/Promise.all是如何工作的 任何帮助我理解为什么我没有得到履行承诺的结果是感激的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('/
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
中,你错过了连接周围的新承诺。如果你把它作为回答,我很乐意接受。