Этот вопрос действительно касается производительности итерации в узле, а не что-то связанного с Firebase, если я правильно понимаю. Вопрос в том, как только у вас будет этот массив из 20000+ объектов, каков наилучший способ повторить их и выполнить операцию над каждым из них?
Существует несколько возможных оптимизаций производительности, которые вы могли бы сделать. Во-первых, вы можете использовать цикл for
, а не Array.prototype.forEach()
, который tends to be faster для очень больших массивов.
...
var len = questionsSnapshot.length;
for (var i = 0; i < len; i++) {
console.log(questionsSnapshot[i].val());
}
Или, используя ES6 for...of синтаксис:
for (let question of questionsSnapshot) {
console.log(question.val());
}
Однако в быстром тесте с использованием console.time() в узле на массиве 20000 объектов, я не заметил последовательное увеличение производительности. Фактически Array.prototype.forEach()
часто был быстрее, чем использование цикла for
.
Другая оптимизация, которую вы можете сделать, - это перемещение вложенного обратного вызова в forEach()
в область видимости модуля. Таким образом, он будет создан только один раз, а не воссоздаваться каждый раз, когда вызывается его родительская функция.
fbase.child("questions").once("value").then(function(questionsSnapshot) {
return questionsSnapshot.forEach(logValue);
});
function logValue(questionSnapshot) {
return console.log(questionSnapshot.val());
}
Однако, это приведет лишь к значительному увеличению производительности, если вы делаете много звонков в родительской функции, то есть, если выполнить ваш запрос Firebase очень часто. Мне кажется, что вопрос скорее связан с повторением большого массива, если у вас уже есть это, а не с тем, чтобы повторять один и тот же запрос много раз.
Итак, если вы хотите выполнить операцию для каждого элемента в своем массиве, я думаю, что вы делаете это нормально. 20000 объектов не так уж и велики; он занимает около 5 мс для итерации через такой массив на моем не впечатляющем компьютере. Фактически, независимо от того, что вы делаете с каждым элементом, скорее всего, потребуется больше времени, чем повторение через массив.
Если вы заметили определенное отставание в производительности, вы можете уточнить, отредактировав сообщение. В противном случае я бы посоветовал не беспокоиться об этом.
Клиент Javascript Firebase поддерживает обещания в настоящее время: https://www.firebase.com/blog/2016-01-21-keeping-our-promises.html. Помимо этого: лучший способ справиться с длинными списками - это избежать их. Как это сделать, зависит от прецедента, который, я сомневаюсь, заключается в их регистрации. –
@FrankvanPuffelen Я понимаю, но как бы вы отправили маркетинговую кампанию по электронной почте всем своим пользователям? Я планирую сохранить /notices/{auth.uid}, и вам нужно выполнить итерацию в запланированном задании. child_added будет эффективно обрабатывать его, но «значение» будет неэффективным [1], поскольку оно хранит элементы в кеше памяти. [1] все содержимое было синхронизировано https://firebase.google.com/docs/reference/js/firebase.database.Reference#on –
@FrankvanPuffelen Я предполагаю, что единственным реальным ответом является использование механизма хранения, который обеспечивает nextPageToken или некоторый тип токена продолжения. Тогда проблема заключается в том, как синхронизировать данные firebase с указанным механизмом хранения. –