使用Firebase返回数组

时间:2013-06-30 15:55:46

标签: node.js firebase q

尝试使用Firebase Node.js时找到在.on("child_added")中使用Q库(或任何类似的库,我不偏袒)返回数据数组的最佳示例;

我尝试过使用Q.all()但似乎永远不会等到承诺在返回之前填写。这是我目前的例子:

function getIndex()
{
    var deferred = q.defer();

    deferred.resolve(new FirebaseIndex( Firebase.child('users').child(user.app_user_id).child('posts'), Firebase.child('posts') ) );

    return deferred.promise;
}

function getPost( post )
{
    var deferred = q.defer();
    deferred.resolve(post.val());
    return deferred.promise;
}

function getPosts()
{
    var promises = [];          

    getIndex().then( function (posts) {
        posts.on( 'child_added', function (_post) {
            promises.push( getPost(_post) );
        });
    });
    return q.all(promises);
}

1 个答案:

答案 0 :(得分:3)

问题出现在getPosts()中。它在一个异步函数中将一个promise推送到你的数组中 - 因为在添加了promise对象之前调用了q.all,所以这是行不通的。

此外,child_added是实时事件通知。你不能用它来获取“所有数据”,因为没有“全部”这样的东西;数据在实时环境中不断变化。 FirebaseIndex也在内部使用child_added回调,因此也无法使用此用例。

您可以使用'value'回调(但不是特定的记录子集)获取所有帖子,如下所示:

function getPosts() {
   var def = q.defer();
   Firebase.child('users').once('value', function(snap) {
      var records = [];
      snap.forEach(function(ss) {
         records.push( ss.val() );
      });
      def.resolve(records);
   });
   return def.promise;
}

但是在这一点上,现在是时候考虑实时环境了。最有可能的是,在开始工作之前,没有理由要求“所有”数据存在。

考虑抓住每条记录进入并将它们附加到需要存储的任何DOM或数组中,并使用事件驱动模型而不是以GET / POST为中心的方法。

幸运的是,你可以完全绕过这个用例。