在继续下一个代码块

时间:2018-04-06 19:36:41

标签: angular typescript ionic-framework

我正在尝试将数据发送到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'];

2 个答案:

答案 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”代替。