Ad

Express Js Deadlock In Promise Inside For Loop

I have an application with node.js and expressjs and now I have a problem when I tried to insert several records into the database.

I have an array with 4 records and the applications insert 3 and the last one returns me a deadlock error from SQL.

I think that problem could be because of the promise inside the for a loop.

Next you have a resume of the code:

 processOrder: (req, res) => {
  //Collecting data for variables
  //Promise to wait for data
  Promise.all([data]).then(function(result)
  {
    //iterate an array
    for (var i = 0; i < result[0].length; i++)
    {
      var new_record = request.query("INSERT INTO table_test (name, local, date) VALUES ('"+result[0][i].name+"', '"+result[0][i].local+"', '"+result[0][i].date+"')");

      //Promise to wait for insert
      Promise.all([ new_record]).then(function(result)
      {
        console.log("Record number "+i+" inserted");
      }).catch(function(err) {
        console.log(err);
        console.log("Erro collecting data");
     });
    }

    console.log("END");
    res.send('true');

  }).catch(function(err) {
    console.log(err);
    console.log("Erro collecting data");
  });

}

The output is:

END
Record number 1 inserted
Record number 2 inserted
Record number 3 inserted
deadlock error

The "END" console.log should be the last log and not the first.

How can I solve this situation? Please explain to me what I'm doing wrong.

Thank you

Ad

Answer

I rewrote your code below.

You can try.

import { request } from "http";

processOrder: (req, res) => {
//Collecting data for variables
//Promise to wait for data

Promise.all([data])
.then(function(result){
  const requests = result[0].map(record => {
      // assume request.query returns promise
      return request.query("INSERT INTO table_test (name, local, date) VALUES ('"+record.name+"', '"+record.local+"', '"+record.date+"')");
  }) 
  Promise.all(requests)
  .then(function(result){
    console.log("END");
    res.send('true');
  })
  .catch(function(err) {
    console.log(err);
    console.log("Erro collecting data");
  });  
})
.catch(function(err) {
  console.log(err);
  console.log("Erro collecting data");
});
}  

If you want to log "Record Number X inserted", then make promised function which execute request.query and console.log.

function requestPromise(queryStmt, index){
    return new Promise(resolve, reject){
        request.query(queryStmt)
        .then(result => {
           console.log(`Record Number ${index} inserted`);
           resolve(result);
        })
        .catch(err){
           reject(err);
        })   
    }
}

and then call above function like this

Promise.all([data])
.then(function(result){
   const requests = result[0].map((record, index) => {
      return requestPromise("INSERT INTO table_test (name, local, date) VALUES ('"+record.name+"', '"+record.local+"', '"+record.date+"')", index);

})

Ad
source: stackoverflow.com
Ad