2017-03-16 83 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

避免[deferred antipattern](http://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-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

是使用$q.all()。將承諾推入陣列,但刪除.then()回調。 Promise.then()返回承諾,因此如果.then()回調沒有被移除,則需要更新它們以返回參數(即result)。

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

然後通過它調用.then()使用$ q.all(承諾),其中true可以返回:

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

看到一個示範this plunker

+0

爲什麼$ q.all(promises).then(function(res){console.log(res)})給出了未定義的? –

+0

@SurajKhanal很難回答這個問題,卻沒有看到'promise'中有什麼。我更新了[plunker示例](https://plnkr.co/edit/CRVDFa)以更好地匹配您的原始代碼(即使用工廠提供商)。 –

+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()做你想做的這種方式。

注: 我認爲所有的錯誤處理程序可以被刪除,只用一個「捕獲」功能

+0

我覺得getData甚至可以''return $ http.get(api +'/ sync /')' – baao

+0

我認爲所有的錯誤處理程序都可以被刪除並且只使用一個「catch」函數 - 但我並不完全確定。我最好放棄它們 - 但我會將它添加爲註釋 –

+0

只要不被攔截器覆蓋,錯誤就可以通過兩種方式獲得。 – baao