當你(在你的情況與on()
)附加一個偵聽的火力地堡數據庫,它從開始從數據庫加載數據。由於這可能需要一些時間,JavaScript代碼將繼續執行,您的代碼將打印空數組。然後,當數據從服務器變爲可用時,調用回調函數並將數據添加到數組中。
這往往是最簡單的跟隨,如果你添加一些日誌語句:
createprofile() {
console.log("Start listening");
this._UserRef.on("value", function(snapshot) {
console.log("Got value");
let items = [];
snapshot.forEach(function(childSnapshot) {
let item = childSnapshot.val();
item['key'] = childSnapshot.key;
items.push(item);
});
this.kitems = items;
}.bind(this));
console.log("After listener");
}
輸出將是:
開始聽
聽衆
了值後
這可能不是您所期望的。但它是現代互聯網編程的本質所固有的。你會遇到大多數API的這種行爲。
一個常見的技巧是在處理這種所謂的異步API時以不同的方式構造代碼。對於傳統的編程,你經常編寫「先得到A,然後做B」。通過一個異步API,將其設置爲「當我們得到A時,我們用它做B」。在你的代碼,這意味着您將所有需要kitems 代碼爲回調函數:
createprofile() {
this._UserRef.on("value", function(snapshot) {
let items = [];
snapshot.forEach(function(childSnapshot) {
let item = childSnapshot.val();
item['key'] = childSnapshot.key;
items.push(item);
});
this.kitems = items;
console.log(this.kitems);
}.bind(this));
}
不只一次的數據已經從服務器返回的kitems纔會被記錄。更好的是:Firebase數據庫同步數據,因此每次數據更改時您的回調將會運行。
由於將需要kitems的代碼放入回調中可能會損害可重用性,因此通常會將回調函數傳遞到數據加載代碼中。
createProfileAndThen(callback) {
this._UserRef.on("value", function(snapshot) {
let items = [];
snapshot.forEach(function(childSnapshot) {
let item = childSnapshot.val();
item['key'] = childSnapshot.key;
items.push(item);
});
this.kitems = items;
callback(this.kitems);
}.bind(this));
}
createProfileAndThen(function(kitems) {
console.log(kitems);
});
這是非常相似的,你進入火力地堡的on()
函數的回調,但隨後爲您的使用情況定製的。
我很確定這是因爲** on **函數是異步的,並且您正在看的控制檯日誌在它運行之前完成。:) – toskv
嘗試調試它;) – toskv