2014-10-10 3 views
5

Это скорее вопрос о закрытии JavaScript, чем вопрос Firebase. В следующем коде обратный вызов 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; 
}; 

ответ

9

Обратный вызов распознавания/модификации myArr совершенно хорошо. Проблема в том, что когда ваш «не работает» - отмечен console.log(myArr), callback еще не уволен.

Давайте изменим код немного:

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 
} 

Теперь это может быть немного легче увидеть, что происходит.

  1. Вы регистрируете слушатель для child_added, который будет вызывать on_post_added на каждый пост, который добавляется к вашему Firebase
  2. Это приведет к вызову к серверу, который может занять значительное количество времени, чтобы вернуть
  3. Между тем ваш код JavaScript продолжается и ...
  4. Регистрирует массив, который на данном этапе по-прежнему пуст
  5. И затем, таким образом, возвращает пустой массив
  6. Теперь в каком-то момент сервер возвращает новое значение (я) и ваш обратный вызов
  7. Это означает, мы можем добавить его в массив без проблем
  8. И войдя на консоль показывает ожидаемые значения

Обработка асинхронный код/​​обратные вызовы, как это требует некоторого привыкания, но имеет решающее значение для работы с 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 
} 
+0

Спасибо за ясный ответ! Как ваш ответ лучше, но я не могу его проголосовать за отсутствие очков пропуска (подсказка). –

+0

Учитывая, что вы задали вопрос, вы должны будете ** принять ** мой ответ, нажав галочку слева. См. Http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work –

+0

Спасибо за ответ. Фрэнк - это просто помогло мне в игре, которую я строю. – Nadjib

1

child_added событие не выполняется немедленно, поэтому не синхронны и вы не можете полагаться на его казнили, до журнала вызова в конце вашей функции.

Процедура:

  • Определение myArr
  • Instantiate Firebase
  • Присвоить обработчик события для child_added
  • Войти значение myArr
  • Return myArr - конец функции
  • сейчас в какой-то момент после этого происходит событие child_added, которое подталкивает к вашему массиву, но, как вы можете видеть, ваше show_fb() весело ction уже завершил выполнение этого пункта.
0

Если Firebase делает вызов ajax (это, вероятно, делает), то функция обратного вызова (моментальный снимок) {..} вызывается после оператора return. Поэтому функция show_fb всегда возвращает [].

, например:

  • Вы выполнить это заявление: вар х = show_fb();
    • show_fb создает пустой массив
    • функция создает АЯКС вызов
    • функция возвращает myArr (пусто на данный момент)
    • переменных й получает ссылку на myArr (массив еще пуст)
    • обратного вызова вызываются и вставляет новое значение х (х и myArr имеют тот же экземпляр)
Смежные вопросы