【问题标题】:angular promise not resolving correctly角度承诺无法正确解决
【发布时间】:2016-03-10 07:38:00
【问题描述】:

我正在努力获得在 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 设置为超时,它会返回相应的数据。

【问题讨论】:

    标签: javascript angularjs q angular-promise


    【解决方案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) 之后 发生。这就是为什么添加超时后它似乎可以工作的原因。

    您需要将您的艺术家集合映射到一个 Promise 集合,然后等待所有这些 Promise 解决。

    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();
    }
    

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2014-01-25
      相关资源
      最近更新 更多