For Loop With Node Js Promise Chaining
Solution 1:
node js current working async
and await
, still now use to async and await
,
use this reference url: https://javascript.info/async-await
async and await is work as promise, await is use to wait to execute script
example
letmcqAll=[]
letsql_test_q_ans='select qId, q_text from questions'
async function showAvatar() {
letresult = await con.query(sql_test_q_ans);
if(result.length > 0){
array.forEach((asyncfunction (item, index, result) {
letq = result[index];
letsql_test_q_ops='SELECT op_text, op_id FROM mc_ops WHERE
q_id='+result[index].q_id
letexecuteQuery = await con.query(sql_test_q_ops);
if(executeQuery.affectedRows > 0){
mcqAll.push({index: q, ops: executeQuery})
console.log(mcqAll);
}
});
}
}
Solution 2:
You have a scope problem here
This is an example to reproduce your problem:
ques
is a global variable that is updated in the for-loop so, when the async code ends the execution will read the global variable with the last ques = result[i]
value.
'use strict'const result = ['a', 'b', 'c']
const mcqAll = []
var ques
for (var i = 0; i < result.length; i++) {
ques = result[i]
var sql_test_q_ops = 'SELECT op_text, op_id FROM mc_ops WHERE q_id = ' + result[i].q_idquery(sql_test_q_ops)
.then(() => {
mcqAll.push({ i: ques })
console.log(mcqAll)
})
}
functionquery() {
returnnewPromise(resolve =>setTimeout(resolve, 100))
}
But, if you simply declare the ques
like this:
for (var i = 0; i < result.length; i++) {
const ques = result[i]
const sql_test_q_op...
all will work.
It is a good practice to use const
or let
instead of var
because the last one creates a global scoped variable that is dangerous.
Regarding your comment: the output is empty because this for-loop is sync, so you reply in sync way to the response.
An example on how to manage this case could be like this:
'use strict'const result = ['a', 'b', 'c']
const mcqAll = []
const promiseArray = result.map(ques => {
const sql_test_q_ops = 'SELECT op_text, op_id FROM mc_ops WHERE q_id = ' + ques.q_idreturnquery(sql_test_q_ops)
.then(() => { mcqAll.push({ i: ques }) })
})
// Wait for all the query to complete before rendering the resultsPromise.all(promiseArray)
.then(() => {
console.log({ mcqAll });
res.render('mcqAllPage', { mcqAll })
})
.catch(err => res.send(500)) // this is an examplefunctionquery() {
returnnewPromise(resolve =>setTimeout(resolve, 100))
}
Consider that there are many possibilities to implement this:
- use for async iterator to run query sequentially
- improve performance by run only one query with a
in
condition instead of a query for eachq_id
and manage the result with some code to group the results - using the promise array as in the example
Go deeper and choose the one that fits best for your need.
Important: .catch
always the promise chain!
Post a Comment for "For Loop With Node Js Promise Chaining"