javascript - Asynchronous node js "For" loop with database query - Stack Overflow

Here is the "for" loop to run query(SQLite3 database) for each "id" in an array.qry

Here is the "for" loop to run query(SQLite3 database) for each "id" in an array.

qry = "SELECT patients.*, patient_visits.visit_id,patient_visits.patient_id, patient_visits.visitdate, patient_visits.visittime FROM patients LEFT JOIN patient_visits ON patients.id = patient_visits.patient_id "+where+" GROUP BY patients.id ORDER BY patients.id  DESC LIMIT "+limit+" OFFSET "+offset;
db.all(qry, (err, results) => {
    if(err){
        response.error = err;
        res.send(response);
    }else{
        response.patients = patients;
        for (var i = 0; i < patients.length; i++) {
            response.patients[i].check = "false";
            var patient = response.patients[i];
            db.each("SELECT visit_id FROM patient_visits where patient_id='"+patient.id+"' AND visitdate >='"+moment().format('YYYY-MM-DD')+"'", function(err, row) {
                if (row) {
                    response.patients[i].check = "true";
                }
            });
        }
    }
    res.send(response);
});

Here is the "for" loop to run query(SQLite3 database) for each "id" in an array.

qry = "SELECT patients.*, patient_visits.visit_id,patient_visits.patient_id, patient_visits.visitdate, patient_visits.visittime FROM patients LEFT JOIN patient_visits ON patients.id = patient_visits.patient_id "+where+" GROUP BY patients.id ORDER BY patients.id  DESC LIMIT "+limit+" OFFSET "+offset;
db.all(qry, (err, results) => {
    if(err){
        response.error = err;
        res.send(response);
    }else{
        response.patients = patients;
        for (var i = 0; i < patients.length; i++) {
            response.patients[i].check = "false";
            var patient = response.patients[i];
            db.each("SELECT visit_id FROM patient_visits where patient_id='"+patient.id+"' AND visitdate >='"+moment().format('YYYY-MM-DD')+"'", function(err, row) {
                if (row) {
                    response.patients[i].check = "true";
                }
            });
        }
    }
    res.send(response);
});

The problem is that the for loop continues before the query is finished. Is there a way to check if the query has finished?

Share Improve this question asked Dec 31, 2018 at 5:56 ShashankShashank 911 silver badge6 bronze badges 1
  • use promise.all – Shailesh Rathod Commented Dec 31, 2018 at 6:04
Add a ment  | 

5 Answers 5

Reset to default 2

pls import async module.

qry = "SELECT patients.*, patient_visits.visit_id,patient_visits.patient_id, patient_visits.visitdate, patient_visits.visittime FROM patients LEFT JOIN patient_visits ON patients.id = patient_visits.patient_id " + where + " GROUP BY patients.id ORDER BY patients.id  DESC LIMIT " + limit + " OFFSET " + offset;
db.all(qry, (err, results) => {
    if (err) {
        response.error = err;
        res.send(response);
    } else {
        response.patients = patients;

        async.forEachOf(patients, function (patient, key, callback) {
            db.each("SELECT visit_id FROM patient_visits where patient_id='" + patients[key] + "' AND visitdate >='" + moment().format('YYYY-MM-DD') + "'", function (err, row) {
                if (row) {
                    response.patients[i].check = "true";
                }else{
                    callback();
                }
            });
        }, function (error) {
            if (error) {
                console.log(error)
            } else {
                res.send(response);
            }
        })

    }
});

Here is the simple way to do but not remended. There is a chance it will execute res.send(response); multiple times. I suggest you learn how to use promise.

qry = "SELECT patients.*, patient_visits.visit_id,patient_visits.patient_id, patient_visits.visitdate, patient_visits.visittime FROM patients LEFT JOIN patient_visits ON patients.id = patient_visits.patient_id "+where+" GROUP BY patients.id ORDER BY patients.id  DESC LIMIT "+limit+" OFFSET "+offset;
db.all(qry, (err, results) => {
    var loopCount = 0;
    if(err){
        response.error = err;
        res.send(response);
    }else{
        response.patients = patients;
        for (var i = 0; i < patients.length; i++) {
            response.patients[i].check = "false";
            var patient = response.patients[i];
            db.each("SELECT visit_id FROM patient_visits where patient_id='"+patient.id+"' AND visitdate >='"+moment().format('YYYY-MM-DD')+"'", function(err, row) {
                if (row) {
                    response.patients[i].check = "true";
                    loopCount++;
                    if(loopCount == patients.length){
                        res.send(response);
                    }
                }
            });
        }
    }

});

Use foreach and something called promises. Since Nodejs is async, to make it wait for query results, you have to use promises.

Use Promise.all to handle multiple asynchronous requests.Write a new function to get the visit_id from the database. Something like this,

function getPatientVisitsByVisitId(visitId){
 // return a new promise.
 }
 let promises= [];
 for(var i = 0; i < patients.length; i++){
  patientVisits.push(getPatientVisitsByVisitId(response.patients[i]));
 }
 Promise.all(promises).then((results) => {
 // results will have visit id's.
 })
 .catch((error) => {
  // handle error here
  })

Is there a way to check if the query has finished?

You can use Promise.all() to know whether all the async calls were pleted or not.

'use strict';

function fetchPatients(where, limit, offset) {
  let qry = "SELECT patients.*, patient_visits.visit_id,patient_visits.patient_id, patient_visits.visitdate, patient_visits.visittime FROM patients LEFT JOIN patient_visits ON patients.id = patient_visits.patient_id " + where + " GROUP BY patients.id ORDER BY patients.id  DESC LIMIT " + limit + " OFFSET " + offset;
  return new Promise((resolve, reject) => {
    db.all(qry, (err, patients) => {
      if (err) {
        return reject(err);
      }
      resolve(patients);
    });
  });
}

function queryVisitsByPatientId(patient) {
  return new Promise((resolve, reject) => {
    patient.check = "false";
    db.each("SELECT visit_id FROM patient_visits where patient_id='" + patient.id + "' AND visitdate >='" + moment().format('YYYY-MM-DD') + "'", function (err, row) {
      if (err) {
        return reject(`Failed for ${patient.id}`);
      }
      if (row) {
        patient.check = "true";
      }
      return resolve(patient);
    });
  });
}

fetchPatients(where, limit, offset).then(patients => {

  let allPatients = patients.map(patient => {
    return queryVisitsByPatientId(patient);
  });

  return Promise.all(allPatients);
}).then(patientDetails => {
  return res.send({
    patients: patientDetails
  });
}).catch(err => {
  return res.send({
    error: err
  });
});

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745080273a4610082.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信