我正在尝试将数据发送到api端点,但由于某些奇怪的原因,我无法弄清楚,数据无法发送。
以下是方法,但是当您检查请求时。
syncPatients(){
let patients = [];
this.sqlite.create({name: 'criticare.db', location: 'default'})
.then((db: SQLiteObject) =>{
db.executeSql('SELECT * FROM patients where updated_at >= (?)',[this.settings.last_sync_time])
.then((data) =>{
if(data.rows.length > 0){
//let patients = [];
for(var i =0; i < data.rows.length; i++){
var _patient = data.rows.item(i);
//console.log(_patient);
db.executeSql('SELECT * FROM wards WHERE id = (?)',[_patient.id])
.then((ward_data)=>{
if(ward_data.rows.length > 0){
_patient.ward_id = ward_data.rows.item(0).online_ref;
patients.push(JSON.stringify(_patient));
//console.log(patients);
}else{
console.log("Ward not found");
}
})
}//end of for loop
}else{
console.log('No patients to sync');
}
})
.then(()=>{
console.log(patients);
var headers = new Headers();
headers.append("Accept", 'application/json');
headers.append('Content-Type', 'application/json; charset=utf-8');
headers.append('Authorization','Bearer '+ this.settings.token);
let options = new RequestOptions({ headers: headers });
let postParams = { patients: JSON.stringify(patients) };
console.log(patients);
this.http.post(this.api_url+"/patients/sync", postParams, options).subscribe(data => {
let response = JSON.parse(data['_body']);
if(response.status == "Ok"){
response.result.forEach(element =>{
db.executeSql('UPDATE patients SET online_ref = (?), updated_at = (?) WHERE id = (?)',[element.online_id, this.getCurrentTime(), element.id]).then(() => {
console.log('Updated patient ' + element.id)
}).catch(e =>{
console.log(e);
})
});
}else{
console.log("Error syncing patients");
}
}) //end of post
})
})
}
问题发生在管理员在.then()
显示let postParams = { patients: JSON.stringify(patients) };
显示patients
之前和之后的最新 {
"patients": ""
}
日志中,但是当您检查请求时,付费负载是
syncPatients(){
let patients = [];
this.sqlite.create({name: 'criticare.db', location: 'default'})
.then((db:SQLiteObject) => {
db.executeSql('SELECT * FROM patients where updated_at >= (?)',[this.settings.last_sync_time])
.then((data) =>{
if(data.rows.length > 0){
for(var i =0; i < data.rows.length; i++){
patients.push(data.rows.item(i));
}
}
else{
console.log('No patients to sync');
}
return patients;
})
.then(async (patients)=>{
const patientsPromises = patients.map(async (patient) =>{
const data = await db.executeSql('SELECT * FROM wards WHERE id = (?)',[patient.id])
patient.ward_id = data.rows.item(0).online_ref
})
// new patients
let all_promises = await Promise.all(patientsPromises);
console.log(patients);
var headers = new Headers();
headers.append("Accept", 'application/json');
headers.append('Content-Type', 'application/json; charset=utf-8');
headers.append('Authorization','Bearer '+ this.settings.token);
let options = new RequestOptions({ headers: headers });
let postParams = { patients: JSON.stringify(patients) };
this.http.post(this.api_url+"/patients/sync", postParams, options)
.subscribe(data => {
let response = JSON.parse(data['_body']);
if(response.status == "Ok"){
this.sqlite.create({name: 'criticare.db', location: 'default'})
.then((db:SQLiteObject) =>{
response.result.forEach(element =>{
db.executeSql('UPDATE patients SET online_ref = (?), updated_at = (?) WHERE id = (?)',[element.online_id, this.getCurrentTime(), element.id])
.then(() => {
console.log('Updated patient ' + element.id)
})
.catch(e =>{
console.log(e);
})
});
})
}else{
console.log("Error syncing patients");
}
}) //end of subscribe
})
})
}
我错过了什么或做错了什么?
更新 结果是@orodan和@ jc-ford建议,问题是在一些承诺解决之前执行http帖子。我已经用他们的建议重构了代码,引入了异步并等待到下面,它现在运行得很好。
$url=wc_get_checkout_url()."/?add-to-cart=".$loop->post->ID."&variation_id=".$variation['variation_id']."&attribute_pa_starter-box=".$variation['attributes']['attribute_pa_starter-box'];
答案 0 :(得分:1)
我相信问题在于你的承诺。请参阅下面的评论。
syncPatients(){
let patients = [];
this.sqlite.create({name: 'criticare.db', location: 'default'})
.then((db: SQLiteObject) =>{
db.executeSql('SELECT * FROM patients where updated_at >= (?)',[this.settings.last_sync_time])
.then((data) =>{
if(data.rows.length > 0){
//let patients = [];
for(var i =0; i < data.rows.length; i++){
var _patient = data.rows.item(i);
//console.log(_patient);
//You're kicking off an asynchronous process here, but not chaining
//its promise to the current promise.
db.executeSql('SELECT * FROM wards WHERE id = (?)',[_patient.id])
.then((ward_data)=>{
if(ward_data.rows.length > 0){
_patient.ward_id = ward_data.rows.item(0).online_ref;
patients.push(JSON.stringify(_patient));
//console.log(patients);
}else{
console.log("Ward not found");
}
})
}//end of for loop
}else{
console.log('No patients to sync');
}
})
.then(()=>{
//This part executes before the executeSql() promises above return
//so the patients.push() above hasn't happened yet.
console.log(patients);
var headers = new Headers();
headers.append("Accept", 'application/json');
headers.append('Content-Type', 'application/json; charset=utf-8');
headers.append('Authorization','Bearer '+ this.settings.token);
let options = new RequestOptions({ headers: headers });
let postParams = { patients: JSON.stringify(patients) };
console.log(patients);
this.http.post(this.api_url+"/patients/sync", postParams, options).subscribe(data => {
let response = JSON.parse(data['_body']);
if(response.status == "Ok"){
response.result.forEach(element =>{
db.executeSql('UPDATE patients SET online_ref = (?), updated_at = (?) WHERE id = (?)',[element.online_id, this.getCurrentTime(), element.id]).then(() => {
console.log('Updated patient ' + element.id)
}).catch(e =>{
console.log(e);
})
});
}else{
console.log("Error syncing patients");
}
}) //end of post
})
})
}
尝试从第一个executeSql()
返回包含在$q.all()
(或者我认为Promise.all()
,如果您处于Angular 2+世界中)的.then()
承诺链接承诺在一起。我认为它们的工作基本相同,但这里是每个文档的链接。
https://docs.angularjs.org/api/ng/service/$q#all
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
答案 1 :(得分:1)
这里有一个异步问题:在进行http呼叫之前,你不要等待你的病房数据在这里。
因为在发出http请求之前必须等待多次调用db,我建议使用Promise.all,它允许你等待所有作为数组参数传递的promise的结束,然后再继续。 它看起来像是这样的:
const dbCalls = [];
for (let i = 0; i < data.rows.length; i++) {
const _patient = data.rows.item(i);
dbCall = db.executeSql('SELECT * FROM wards WHERE id = (?)',[_patient.id]);
}
Promise.all(dbCalls)
.then(dbResults => {
dbResults.forEach(ward_data => {
if (ward_data.rows.length > 0) {
_patient.ward_id = ward_data.rows.item(0).online_ref;
patients.push(JSON.stringify(_patient));
} else {
console.log("Ward not found");
}
});
console.log(patients);
var headers = new Headers();
headers.append("Accept", 'application/json');
headers.append('Content-Type', 'application/json; charset=utf-8');
headers.append('Authorization','Bearer '+ this.settings.token);
let options = new RequestOptions({ headers: headers });
let postParams = { patients: JSON.stringify(patients) };
console.log(patients);
this.http.post(this.api_url+"/patients/sync", postParams, options).subscribe(data => {
let response = JSON.parse(data['_body']);
if(response.status == "Ok"){
response.result.forEach(element =>{
db.executeSql('UPDATE patients SET online_ref = (?), updated_at = (?) WHERE id = (?)',[element.online_id, this.getCurrentTime(), element.id]).then(() => {
console.log('Updated patient ' + element.id)
}).catch(e =>{
console.log(e);
})
});
}else{
console.log("Error syncing patients");
}
}) //end of post
})
至于为什么在调试时看到你的病人:不要信任console.log。因为您有异步问题,在某个时间点,您的数据库调用已完成,您的患者已填充。 console.log为您提供了患者的“最新版本”,但是当时您正在尝试进行http呼叫,但他们还没有来这里^^
PS:我在我的例子中使用了一些ES6语法,你不能用“function”和任何const替换箭头函数,而是用“var”代替。