2016-05-02 3 views
0

У меня есть функция в моем приложении React-native, в котором я прокручиваю ключи в массиве и вытягиваю соответствующий ref из Firebase.Изменить собственный ключ, не обновляющийся должным образом в for-loop?

Тем не менее, в пределах моих цикл, хотя правильный порядковый всегда оценивается, ключевое значение внутри самой для петли всегда 3, и, следовательно, totalItemsCompleted (которая равна длине стоимости ключа в userItemsArray) является всегда равна 3.

listenForItems(itemsRef) { 
    var userItemsArray = { 
     0: [1], 
     1: [5, 6], 
     2: [8, 9, 10], 
     3: [11, 12, 13] 
    }; 

    var pastItems = []; 
    var currentItems = []; 

    for (var key in userItemsArray) { 
     console.log("KEY1 " + key); //key is correct here 
     var itemRef = itemsRef.child(key); 
     itemRef.on('value', (snap) => { 
      var totalItemsOnList = snap.val().items.length; 
      var totalItemsCompleted = userItemsArray[key].length; 
      console.log("KEY2 " + key); //key is always 3 here 
      if (totalItemsOnList===totalItemsCompleted) { 
       pastItems.push({ 
        title: snap.val().title, 
      }); 
      } 
      else { 
       currentItems.push({ 
        title: snap.val().title, 
       }); 
      } 

      this.setState({ 
       currentItems: this.state.currentItems.cloneWithRows(currentItems), 
       pastItems: this.state.pastItems.cloneWithRows(pastItems) 
      }); 
     }); 
    } 
} 
+2

Добро пожаловать в удивительный мир асинхронного программирования. Цикл for не ждет завершения вызова firebase, чтобы он продолжал обновлять значение ключа. Можете ли вы попытаться сделать console.log (snap.name()) вместо ключа? –

+0

@ AndréKool aha! Это верно; Теперь я использую snap.key() и получаю правильное значение (snap.name() скоро устареет). Спасибо! – user3802348

+1

Отлично, я добавлю его в качестве ответа, чтобы он мог помочь другим людям, когда они также столкнулись с этой проблемой. И я сомневался между именем и ключом, и я просто взял первый, который нашел в google search :) –

ответ

1

Проблема здесь асинхронная природа firebase , Цикл for не ждет завершения вызова firebase, чтобы он продолжал обновлять значение ключа.

Insead использования ключа переменной следует использовать ключ вашего firebase снимка, как это:

var itemRef = itemsRef.child(key); 
    itemRef.on('value', (snap) => { 
     var totalItemsOnList = snap.val().items.length; 
     var totalItemsCompleted = userItemsArray[snap.key()].length; 
     console.log("KEY2 " + snap.key()); 
1

Тот же поток может быть легко воспроизведен со следующим кодом:

for(var i= 0; i< 3; i++) setTimeout(()=> alert(i) ,i * 1000) 

Хотя вы создаете несколько экземпляров анонимной функции она не заблокирована на соответствующий key, но вместо этого ссылайтесь на его «по имени». Итак, если какая-либо из обработанной обработчиком переменной key содержит последнее значение, полученное во время цикла.

Существуют различные способы борьбы с этим. Простейших является обернуть создание обработчика в себя вызываемый анонимную функцию:

temRef.on('value', ((keyFixedValue) => { 
return (snap) => {/*all other code*/} 
})(key)) 

Другой возможным способ о хранении key в качестве значения атрибута соответствующего HTML элемента

Смежные вопросы