带有数据库查询的异步节点js“ For”循环

时间:2018-12-31 05:56:20

标签: javascript node.js electron desktop-application

这里是“ for”循环,用于对数组中的每个“ id”运行查询(SQLite3数据库)。

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);
});

问题在于for循环在查询完成之前会继续。有没有办法检查查询是否完成?

5 个答案:

答案 0 :(得分:1)

这是简单的方法,但不建议这样做。它有可能多次执行res.send(response);。 我建议您学习如何使用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);
                    }
                }
            });
        }
    }

});

答案 1 :(得分:1)

使用foreach和称为promise的东西。由于Nodejs是异步的,因此要使其等待查询结果,您必须使用Promise。

答案 2 :(得分:1)

使用Promise.all处理多个异步请求。编写一个新函数以从数据库中获取visit_id。像这样的东西

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
  })

答案 3 :(得分:1)

  

是否可以检查查询是否已完成?

您可以使用Promise.all()来了解所有异步调用是否都已完成。

'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
  });
});

答案 4 :(得分:1)

pls导入异步模块。

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);
            }
        })

    }
});