与Firebase问题相比,这更像是JavaScript关闭问题。在以下代码中,Firebase回调无法识别父作用域中的变量myArr。
function show_fb() { var myArr = []; var firebase = new Firebase('https://scorching-fire-6816.firebaseio.com/'); firebase.on('child_added', function(snapshot) { var newPost = snapshot.val(); myArr.push(newPost.user); console.log(myArr); // works }); console.log(myArr); // doesn't work. myArr in the firebase.on callback is // not altering myArr return myArr; };
回调函数可以myArr很好地识别/修改。问题是,当console.log(myArr)执行标记为“不工作”的标签时,回调尚未触发。
myArr
console.log(myArr)
让我们稍微更改一下代码:
var myArr = []; function show_fb() { var firebase = new Firebase('https://scorching-fire-6816.firebaseio.com/'); firebase.on('child_added', on_post_added); // steps 1-3 console.log(myArr); // step 4 return myArr; // step 5 }; function on_post_added(snapshot) { // step 6 var newPost = snapshot.val(); myArr.push(newPost.user); // step 7 console.log(myArr); // step 8 }
现在,可能会更容易了解发生了什么。
child_added
on_post_added
像这样处理异步代码/回调需要一些时间,但是对于使用Firebase或任何其他类似AJAX或事件驱动的技术来说至关重要。将回调的代码放在单独的函数中有时会使查看正在发生的事情变得容易一些。
对于Firebase,它也可能有助于认识到事件被调用child_added是有原因的。每当将孩子添加到Firebase中时,就会调用此方法,而不仅仅是在您首次注册回调时。因此,几分钟后,当其他客户端添加了一个子代时,您的回调仍将触发,从而将一个新的子代添加到myArr。在那个阶段,以上步骤4和5中的代码将长期执行,并且不会再次执行。
解决方案很简单:在将孩子添加到回调中之后,将您要执行的任何操作放入:
var myArr = []; function show_fb() { var firebase = new Firebase('https://scorching-fire-6816.firebaseio.com/'); firebase.on('child_added', on_post_added); }; function on_post_added(snapshot) { var newPost = snapshot.val(); myArr.push(newPost.user); console.log(myArr); // do whatever else you need to do for a new post }