2016-12-03 55 views
0

構建帶有Ionic框架和Firebase的JS應用程序。如何處理修改同一變量的遞歸異步數據庫調用

我希望應用根據他們訪問的國家/地區向每個用戶建議一系列用戶進行討論。建議列表中首先介紹最常用國家/地區的用戶,而不是當前用戶。

我有兩個表中火力地堡:

"users" : { 
"userA" : { 
    "countries" : [ { 
    "id" : 4, 
    "name" : "france" 
    }, { 
    "id" : 2, 
    "name" : "spain" 
    } ] 
}, 
"userB" : { 
    "countries" : [ { 
    "id" : 4, 
    "name" : "france" 
    }, { 
    "id" : 2, 
    "name" : "russia" 
    } ] 
}, 
"userC" : { 
    "countries" : [ { 
    "id" : 4, 
    "name" : "france" 
    }, { 
    "id" : 2, 
    "name" : "spain" 
    } ] 
} 

和索引表:

"country_user" : { 
    "france" : { "userA" : true, "userB" : true, "userC" : true }, 
    "spain" : { "userA" : true, "userC" : true }, 
    "russia" : { "userB" : true } 
} 

在前端我想$ scope.matches存儲用戶的排行榜中名列如上所述。

在服務器端,我實現以下邏輯:

  1. 檢索當前用戶已訪問過的國家的名單,並在表中返回一個承諾與這些國家
  2. 對於每一個國家獲取country_user列表對應於該國
  3. 創建一個「匹配」陣列,解析的2各自結果和更新「匹配」陣列

無極1的用戶:

function getUserCountryListPromise(_uid){ 
     return firebase.database().ref('users/' + user.uid + '/countries/').once('value').then(function(snap){ 
      var userCountryList = []; 
      if(snap.exists()){ 
      snap.forEach(function(country){ 
       userCountryList.push(country.val().name); 
      }); 
      } 
      return userCountryList; 
     }); 
     } 

我開始實施2,但我堅持:

function getRegistrationsToCountries(_country){ 
     return firebase.database().ref('/country_user/' + _country).once('value').then(function(snap){ 
      if(snap.exists()){ 
      snap.forEach(function(registeredUser){ 


     }); 
     } 

如果用戶A的我想打電話給getRegistrationsToCountries兩次,只有當這兩個呼叫完成(但電話號碼是動態)我想解析它們以更新我想返回到前端的「匹配」列表。

有什麼建議嗎?

感謝

回答

0

使用上承諾的哈希$q.all方法:

function getRegistrationsFromCountryList(countryList){ 
    var promiseHash = {}; 
    countryList.foreach(function (country) { 
     promiseHash[country] = firebase.database().ref('/country_user/' + country).once('value'); 

    }); 
    return $q.all(promiseHash); 
}; 

上面的例子返回解析爲countryList鍵入每個國家註冊的哈希的承諾。

爲了與countryListPromise使用時,只需鏈中的承諾:

var promise = getUserCountryListPromise(uid); 

var registrationsHashPromise = promise.then(function(countryList) { 
    //return promise to chain 
    return getRegistrationsFromCountryList(countryList); 
}); 

registrationsHashPromise.then(function(regsHash) { 
    angular.forEach(regsHash, function(regs, country) { 
     console.log(country + ": " + regs); 
     //update matches list 
    }); 
}); 

,因爲調用一個承諾的.then方法返回一個新派生的承諾,這是很容易可以創建承諾的一個鏈條。有可能創建任意長度的鏈,並且由於承諾可以通過另一個承諾來解決(這會進一步延遲其解決方案),因此可以在鏈中的任何時刻暫停/推遲解決承諾。這使得實現強大的API成爲可能。

- AngularJS $q Service API Reference -- Chaining Promises

+0

謝謝喬治您的答案!我試圖實現你的解決方案,但我有$ q(未定義)的引用錯誤,但我認爲我注入它正確:'.service('UserService',['$ q',function($ q){'am做錯了什麼? –