2013-06-30 103 views
1

嘗試查找使用Firebase .on("child_added")與Q庫(或任何類似的庫,我不是部分)在Node.js中返回數據數組的最佳用法示例;使用Firebase返回陣列

我已經嘗試過使用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); 
} 
+0

JS沒有辦法在代碼中「封鎖」。所有q.all()都會做的是創建一個新的承諾,在其他一切完成時完成。但它沒有辦法讓它們等待它們完成。 JS不以這種方式工作... –

回答

3

getPosts()發生此問題。它在一個異步函數內將一個承諾推入你的數組 - 這是行不通的,因爲在添加承諾對象之前調用q.all。

另外,child_added是一個實時事件通知。你不能用它來獲取「所有數據」,因爲沒有「全部」這樣的東西。數據在實時環境中不斷變化。 FirebaseIndex也在內部使用child_added回調函數,所以這也不適用於這個用例。

你可以抓住所有使用「值」回調(但記錄不是特定子集)的職位如下:

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居中方法。

幸運的是,你完全可以繞過這個用例。

+0

不知道這段代碼是否正常工作,在我的機器上,我不得不使用大寫字母Q,並且沒有括號(不使用節點,也許它不同) –

+0

在節點中,指定名字對象Q和Q)在require命令中。 – Kato