我有以下代码,这是通过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;
}
正如评论中有人提到的,我缺少的主要东西是我第二个连接周围的一个新的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
获取未定义值数组的原因是返回的是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容器状态列表。但是安慰。日志(列表)返回未定义的。 有人能帮我吗?:)