2016-03-09 1 views
1

Я работаю над получением обещания решить после запроса Firebase. По сути, я хочу получить все указанные ключи из таблицы, а затем прокрутить другую таблицу, чтобы получить требуемые иллюстрации.Угловое обещание не разрешается правильно

artistFactory.js

'use strict'; 

angular.module('artvoicesApp') 
    .factory('Artist', function(localStorageService, FIREBASE_URL, $q) { 

    var artistData = {}; 
    var userKey = localStorageService.get('userKey'); 
    var accountKey = localStorageService.get('accountKey'); 
    var artistRef = FIREBASE_URL.child('v2/artist'); 
    var accountRef = FIREBASE_URL.child('v2/account/' + accountKey); 
    var userRef = FIREBASE_URL.child('v2/user/' + userKey); 

    artistData.addArtist = function(artistName) { 
     var artist = artistRef.push(); 
     accountRef.child('artists/' + artist.key()).set(true); 
     userRef.child('artists/' + artist.key()).set(true); 
     artist.set({name: artistName}); 
     artist.child('users/' + userKey).set(true); 
     artist.child('accounts/' + accountKey).set(true); 
    }; 

    artistData.getArtistKeys = function() { 
     var artistKeys = []; 
     var defer = $q.defer(); 
     accountRef.child('artists').once('value', function(snapshot) { 
     snapshot.forEach(function(childSnapShot) { 
      artistKeys.push(childSnapShot.key()); 
     }); 
     defer.resolve(artistKeys); 
     }); 
     return defer.promise; 
    }; 

    artistData.getArtists = function(artistKeys) { 
     var artistObj = {}; 
     var artistRef = FIREBASE_URL.child('v2/artist'); 
     var defer = $q.defer(); 

     artistKeys.forEach(function(artist) { 
     artistRef.child(artist).once('value', function(snapshot) { 
      artistObj[artist] = snapshot.val(); 
     }); 
     defer.resolve(artistObj); 
     }); 
     return defer.promise; 
    }; 

    return artistData; 
    }); 

artwork.controller.js

Artist.getArtistKeys().then(function(artistKeys) { 
    Artist.getArtists(artistKeys).then(function(artists) { 
     vm.artists = artists; 
     console.log(vm.artists); 
    }); 
}); 

Если установить vm.artwork тайм-аута, он возвращает соответствующие данные.

ответ

1

Вот ваша проблема:

artistKeys.forEach(function(artist) { 
    artistRef.child(artist).once('value', function(snapshot) { 
     artistObj[artist] = snapshot.val(); // <<== This is called second, at an unspecified time in the future 
    }); 
    defer.resolve(artistObj); // <<== This is called first 
    }); 

Все ваши присвоений artistObj будет происходить через некоторое время после того, как вы назвали defer.resolve(artistObj). Вот почему он появился, если вы добавили тайм-аут.

Вам нужно будет сопоставить коллекцию художников с коллекцией обещаний, а затем дождаться решения всех этих обещаний.

artistData.getArtistKeys = function(artistKeys) { 
    var artistObj = {}; 
    var artistRef = FIREBASE_URL.child('v2/artist'); 
    var allPromises = artistKeys.map(function(artist) { 
    var childDefer = $q.defer(); 
    artistRef.child(artist).once('value', function(snapshot) { 
     artistObj[artist] = snapshot.val(); 
     childDefer.resolve(); 
    }); 
    return childDefer.promise(); 
    }); 
    // allPromises is now an array of promises 
    var defer = $q.defer(); 
    $q.all(allPromises).then(function() { 
    defer.resolve(artistObj); 
    }); 
    return defer.promise(); 
} 
+0

Большое спасибо. Это работает как шарм. –