2017-03-16 14 views
2

私は、APIからデータを取得し、各データをSQLLiteデータベースに保存する私の工場です。はangularjsの複数の約束を解決します

team.factory('dataSync', function($q,$http,$timeout,$cordovaSQLite){ 
    return { 
     getData:function(){ 
      var q = $q.defer(); 
      $http.get(api+'/sync/').then(function(response){ 
       q.resolve(response); 
      },function(error){ 
       q.reject(); 
      }) 
      return q.promise; 

     }, 

     saveData:function(){ 
      var q= $q.defer(); 

      this.getData().then(function(result){ 
       var data= result.data; 
       var sharing = data.sharing; 
       var help = data.help; 
       var message = data.message; 
       var questions = data.question; 

       var promises = []; 

       angular.forEach(sharing, function(value, index) { 
         console.log(value); 
        var sharingsql="INSERT INTO sharing (id,content_order,content ,last_modified)VALUES(?,?,?,?)"; 

        $cordovaSQLite.execute(db,sharingsql,[value.id,value.content_order,value.content,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
         //q.resolve(true); 
        },function(error){ 
         console.log(error.message); 
        }) 
       }); 
       angular.forEach(help, function(value, index) { 
        console.log(value.message); 
        var helpsql="INSERT INTO help (id,message,message_position,last_modified)VALUES(?,?,?,?)"; 

        $cordovaSQLite.execute(db,helpsql,[value.id,value.message,value.message_position,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        }) 
       }); 

        angular.forEach(message, function(value, index) { 
        var messagesql="INSERT INTO messages (id,message,message_position,last_modified_date)VALUES(?,?,?,?)"; 

        $cordovaSQLite.execute(db,messagesql,[value.id,value.message,value.message_position,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        }) 
       }); 

        angular.forEach(questions, function(value, index) { 
        console.log(value.id+' '+index); 
        var questionsql="INSERT INTO questions (id,question_status,questions,question_order,last_modified)VALUES(?,?,?,?,?)"; 

        $cordovaSQLite.execute(db,questionsql,[value.id,value.question_status,value.question,value.question_order,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        }) 
       }); 


        $timeout(function(){ 

        },2000).then(function(){ 

         //q.resolve(true); 
        }) 


      },function(error){ 
       q.reject(); 
      }); 
      return q.promise; 
     } 

    } 
}); 

$cordovaSQLite.executeの呼び出しは約束を返します。

私は約束がすべて解決された後にtrueを返信したいと思います。各ループで解決される約束をすべて解決するにはどうすればよいですか?

これについて検索したところ、答えは$q.allでした。それから私はこれについていくつかのチュートリアルを読みましたが、ここで実装することはできません。

+1

[遅延反パターン]を避けてください(http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-struction-antipattern-and-how-to-avoid-it)! – Bergi

+2

[AngularJS - 複数のリソースクエリが完了するのを待つ]の可能な複製(http://stackoverflow.com/questions/15299850/angularjs-wait-for-multiple-resource-queries-to-complete) –

+0

はい、 '$ q .allは答えです。どのように使用しようとしたのか教えてください。 – Bergi

答えて

1

はいを​​使用することができると思います。約束を配列にプッシュしますが、.then()コールバックは削除してください。 Promise.then()は約束を返します。したがって、.then()コールバックが削除されない場合は、引数を返すように更新する必要があります(つまりresult)。 trueを返すことができる場所

promises.push($cordovaSQLite.execute(db,sharingsql,[value.id,value.content_order,value.content,value.last_modified])) 

すると、それに.then()を呼び出すことにより、$のq.all(約束)を使用します。

$q.all(promises) 
    .then(function(responses) { 
    //all promises have been resolved 
    return true; 
    }) 

this plunkerでデモを参照してください。

+0

なぜ$ q.all(約束しますか).then(関数(res){console.log(res)})は未定義ですか? –

+0

@SurajKhanal「約束事」に何が入っているかを見ることなく、その質問に答えることは難しいです。 [plunker example](https://plnkr.co/edit/CRVDFa)を更新して元のコードをより良く(つまり、工場提供者を使用して)一致させました。 –

+0

ok問題を解決しました。私は関数を返すのを忘れてしまった –

2

は配列にすべての約束を配置し、ここで$q.all(yourArray).

を使用し、あなたの更新されたコードがある - あなたはすでに約束を返し$http以来$q.defer()を使用する必要はありません - とすべてのあなたの$cordovaSQLite約束は自分自身で解決されます

team.factory('dataSync', function($q,$http,$timeout,$cordovaSQLite){ 
    return { 
     getData:function(){ 
      return $http.get(api+'/sync/').then(function(response){ 
       return response; 
      },function(error){ 
       $q.reject(); 
      }) 
     }, 
     saveData:function(){ 
      return this.getData().then(function(result){ 
       var data= result.data; 
       var sharing = data.sharing; 
       var help = data.help; 
       var message = data.message; 
       var questions = data.question; 

       var promises = []; 

       angular.forEach(sharing, function(value, index) { 
         console.log(value); 
        var sharingsql="INSERT INTO sharing (id,content_order,content ,last_modified)VALUES(?,?,?,?)"; 

        promises.push($cordovaSQLite.execute(db,sharingsql,[value.id,value.content_order,value.content,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
         //q.resolve(true); 
        },function(error){ 
         console.log(error.message); 
        })); 
       }); 
       angular.forEach(help, function(value, index) { 
        console.log(value.message); 
        var helpsql="INSERT INTO help (id,message,message_position,last_modified)VALUES(?,?,?,?)"; 

        promises.push($cordovaSQLite.execute(db,helpsql,[value.id,value.message,value.message_position,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        })); 
       }); 

        angular.forEach(message, function(value, index) { 
        var messagesql="INSERT INTO messages (id,message,message_position,last_modified_date)VALUES(?,?,?,?)"; 

        promises.push($cordovaSQLite.execute(db,messagesql,[value.id,value.message,value.message_position,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        })); 
       }); 

        angular.forEach(questions, function(value, index) { 
        console.log(value.id+' '+index); 
        var questionsql="INSERT INTO questions (id,question_status,questions,question_order,last_modified)VALUES(?,?,?,?,?)"; 

        promises.push($cordovaSQLite.execute(db,questionsql,[value.id,value.question_status,value.question,value.question_order,value.last_modified]).then(function(result){ 
         console.log(result.insertId); 
        },function(error){ 
         console.log(error.message); 
        })); 
       }); 
       return $q.all(promises); 
      },function(error){ 
       return $q.reject(); 
      }); 
     } 
    } 
}); 

あなたはsaveData()それはすべてあなたの$cordovaSQLiteが解決され、そしてすべてのことが起こるの後、あなたがやりたい.then()を使用することができ、一度に解決される約束を返します呼び出すこの方法では。

注: は、私はすべてのエラーハンドラが削除され、$q.all()を使用する唯一の「キャッチ」機能

+0

getDataは 'return $ http.get(api + '/ sync /')' – baao

+0

でもかまいません。すべてのエラーハンドラを削除し、 "catch"関数を1つしか使用できないと思います。私はそれらを残しておくことをお勧めします - しかし、これをコメントとして追加します –

+0

傍受者によってオーバーライドされない限り、エラーは両方の方法で同じようにキャッチすることができます。 – baao

関連する問題