当你(在你的情况与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