解决angularjs中的多个承诺

时间:2017-03-16 18:14:30

标签: javascript angularjs angular-promise

这是我的工厂,它从API获取数据并将每个数据存储到SQLLite数据库。

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作为答案。然后我读了一些关于这个的教程,但是不能在这里实现。

2 个答案:

答案 0 :(得分:2)

将所有承诺放入数组中,然后使用$q.all(yourArray).

以下是您的更新代码 - 您不需要使用$q.defer(),因为$http已经返回承诺 - 您的所有$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()完成所需后的操作发生。

注意: 我认为可以删除所有错误处理程序,只使用一个" catch"功能

答案 1 :(得分:1)

是使用$q.all()。将promises推送到数组中,但删除.then()回调。 Promise.then()会返回一个承诺,因此如果.then()回调未被删除,则需要更新它们以返回参数(即result)。

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

然后通过调用.then()来使用$ q.all(promises),其中true可以返回:

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

参见this plunker中的演示。