这里是“ 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循环在查询完成之前会继续。有没有办法检查查询是否完成?
答案 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);
}
})
}
});