如何解决在Node中与MySQL结果异步/等待问题
我有以下代码,这是通过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函数内部返回任何内容,因此它将解析为undefined。
我想重构您的代码以更好地理解。您应该在Promise.all()调用中包含一个Promise数组。
类似的东西:
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;
,
正如评论中提到的某个人,我最想念的是围绕我的第二个连接的一个新的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/@amymurphy_40966/node-mysql-chained-promises-vs-async-await-9d0c8e8f5ee1
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。