我知道这个问题可能已经有人问过了。但我不明白事情是如何运作的。这就是我创建新线程的原因。
con.query(sql,[req.params.quizId],(err,rows,fields)=>{
//rows contains questions
if(err) throw err;
else{
let object={};
rows.forEach((item,index)=>{
object=item;
//here iam passing question id to get choices a async function
getChoices(item.id)
.then(data=>{
object.choices=data;
//save the question array
response.push(object);
//res.send(response);
});
})
res.send(response) //return empty array
}
});
function getChoices(questionId) {
let sql='SELECT id,text FROM `question_choices` where question_id=?';
return new Promise((resolve, reject) => {
con.query(sql,[questionId],(err,rows,fields)=>{
if(err) throw err;
else {
resolve(rows);
}
})
})
}
我尝试了几种方法,但都没有用。我认为 for loop 没有等待 promise 完成,而是直接发送响应。那里发生了一些异步问题。
我可以从数据库中获取所有问题,并且对于每个问题我都需要获得我想要的相应选项。
像这样的
[{id:'xx', text:'yy',choices:[{id:'c',text:'kk']},etc]
最佳答案
forEach
同步 运行。您正在寻找 Promise.all
,它接受 Promise
数组,并在所有 Promise 都解析后解析为已解析值的数组。要将 rows
数组转换为 Promises
数组,请使用 .map
。
此外,当出现错误时,您应该调用reject
以便您可以在Promise
的消费者中处理错误(con.query
callback),否则,当出现错误时,它会在你不知情的情况下永远挂起:
con.query(sql,[req.params.quizId],(err,rows,fields)=>{
if(err) throw err;
Promise.all(rows.map((item) => (
getChoices(item.id)
.then((choices) => ({ ...item, choices }))
)))
.then((response) => {
res.send(response);
})
.catch((err) => {
// handle errors
})
});
function getChoices(questionId) {
const sql='SELECT id,text FROM `question_choices` where question_id=?';
return new Promise((resolve, reject) => {
con.query(sql,[questionId],(err,rows,fields)=>{
if(err) reject(err);
else resolve(rows);
});
});
}
关于javascript - 在nodejs中等待循环内的 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53455709/