Я столкнулся с проблемой, когда у меня есть массив с загадочными дубликатами.
В firebase мой объект содержит массив
{
ink_colors:
0: 'Mauve',
1: 'Mineral',
2: 'Mocha',
3: 'Navy'
}
Веб-консоль Firebase:
Когда объект получен моим приложением React, консоль сообщает
console.info(snapshot.val().ink_colors);
> Array(4) [ "Mauve", "Mineral", "Mocha", "Navy" ]
НО
при доступе к массиву он, по-видимому, имеет 6 элементов
temp1.ink_colors
// => [ "Mauve", "Mineral", "Mocha", "Navy", "Mauve", "Mauve" ]
Пытаясь отладить эту проблему с помощью журнала консоли и отладчика, я сохраняю вывод консоли в глобальной переменной temp1 и получаю два разных результата:
function receive(payload){
console.info(payload);
debugger;
}
> payload.ink_colors
< (4) ["Mauve", "Mineral", "Mocha", "Navy"]
> temp1.ink_colors
< (6) ["Mauve", "Mineral", "Mocha", "Navy", "Mauve", "Mauve"]
что говорит мне, что проблема заключается в том, что нет типичная ловушка массива firebase с неожиданными пустыми значениями массива.
Пакеты НПМ:
реагировать: 16.8.2
редукс: 4.0.1
база данных: 5.7.2
Мне кажется очевидным, что что-то добавляет две дополнительные записи "Mauve" после того, как вы регистрируете массив. Однострочный вывод log показывает массив в том виде, в котором он существует на момент регистрации, а расширение этой записи показывает массив на момент расширения. Массив получает дополнительные записи между временем, когда вы его регистрируете, и временем, когда вы его расширяете. Я подозреваю, что невозможно сказать, что выполняет эти нежелательные дополнения, не видя больше кода.
Вы должны проксировать свой массив и отлаживать вызываемый метод.
Можете ли вы показать весь код, который вы используете для чтения базы данных? не только snapshot.val().ink_colors, но и как вы получаете snapshot
Нам не хватает полного кода, который воспроизводит здесь проблему. Сказать нам, что это правильно в одном месте, но не в другом, — это хорошая формулировка проблемы, но недостаточно хорошая, чтобы помочь вам. Попробуйте воспроизвести проблему в одном фрагменте автономного кода, который может легко запустить любой. См. как создать минимальный, полный, проверяемый пример.
См. эта рабочий пример для демонстрации комментария @apsillers выше. Консоль регистрирует массив из пяти элементов, расширение показывает шесть.
Команды console.info буферизуются и не синхронизируются. Когда журнал действительно выполняется, размер массива изменился из-за команды push. Если вы переключите это на console.info(array.slice(0));, вы увидите правильный счет. Это не воспроизводит поведение, описанное в оп. Все еще нужна минимальная репродукция, чтобы понять, почему в списке 2 лишних Mauve. Никакой код здесь не создает это условие.
Смотрите мой ответ, как вы можете исправить это путем отладки.
Ах, я не знал, что console.info будет регистрировать текущее значение, а затем отображать другое значение. Действительно, метод помещал записи в конец массива, чего можно было бы избежать, используя .slice() для копирования массива. Я так и подозревал, но думал, что проблема глубже из-за неожиданного (для меня) логирования. Спасибо за вашу помощь!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Пожалуйста, убедитесь, что вы не добавляете элементы дважды, в случае правильного выполнения вы можете улучшить фильтрацию результирующего массива в новый массив уникальных элементов.
Взгляните на:получить-все-уникальные-значения-в-массиве-javascript-удалить-дубликаты
Также это может быть проблема с методом добавления элементов в firebase.
Кажется, у вас где-то есть код, меняющий значение. Возьмите это, например:
let arr = ["Mauve", "Mineral", "Mocha", "Navy"];
debugger
// somewhere in the code, the arr is being modified
arr.length = 6;
arr.fill('Mauve', -2)
// where you are trying to log arr
console.info(arr)Теперь откройте инструмент разработчика и запустите приведенный выше фрагмент, вы увидите, что длина arr равна 4. Но на самом деле вы можете видеть, что длина arr равна 6, и вы заметили, что она изменяется после использования debugger.
И если вы не можете найти виновника, вы можете попробовать грязное исправление, используя Object.freeze:
let arr = ["Mauve", "Mineral", "Mocha", "Navy"];
Object.freeze(arr)
// somewhere in the code, the arr is being modified
arr.length = 6;
arr.fill('Mauve', -2)
// where you are trying to log arr
console.info(arr)После этого вы сможете увидеть реальную проблему, содержащую строку, в которой используется такая модификация файла. Например. здесь, во фрагменте, вы можете увидеть:
Error: {
"message": "Uncaught TypeError: Cannot assign to read only property '2' of object '[object Array]'",
"filename": "https://stacksnippets.net/js",
"lineno": 17,
"colno": 5
}
Итак, теперь вы знаете, где это. И вы можете, наконец, решить проблему, а затем снова удалить Object.freeze.
Что-то еще обращается к нему, настраивая его? Трудно понять, что происходит, не видя больше кода.