Skip to content Skip to sidebar Skip to footer

For Loop With Node Js Promise Chaining

I am very new to Node js and asynchronous programming seems difficult for me to grasp. I am using promise-mysql to make the flow synchronous but I have hit a road block with for lo

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 each q_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"