2016-02-20 9 views
0

В настоящее время я использую Fireproof сделать это обещание на основе, и вот что у меня есть:Как выполнить итерацию через большой набор данных с помощью Firebase/Node.js?

fbase.child("questions").once("value").then(function(questionsSnapshot) { 
    return questionsSnapshot.forEach(function(questionSnapshot) { 
    return console.log(questionSnapshot.val()); 
    }); 
}); 

Но questions огромен. 20000 записей. Не уверен - есть ли лучший способ?

+2

Клиент Javascript Firebase поддерживает обещания в настоящее время: https://www.firebase.com/blog/2016-01-21-keeping-our-promises.html. Помимо этого: лучший способ справиться с длинными списками - это избежать их. Как это сделать, зависит от прецедента, который, я сомневаюсь, заключается в их регистрации. –

+0

@FrankvanPuffelen Я понимаю, но как бы вы отправили маркетинговую кампанию по электронной почте всем своим пользователям? Я планирую сохранить /notices/{auth.uid}, и вам нужно выполнить итерацию в запланированном задании. child_added будет эффективно обрабатывать его, но «значение» будет неэффективным [1], поскольку оно хранит элементы в кеше памяти. [1] все содержимое было синхронизировано https://firebase.google.com/docs/reference/js/firebase.database.Reference#on –

+0

@FrankvanPuffelen Я предполагаю, что единственным реальным ответом является использование механизма хранения, который обеспечивает nextPageToken или некоторый тип токена продолжения. Тогда проблема заключается в том, как синхронизировать данные firebase с указанным механизмом хранения. –

ответ

4

Этот вопрос действительно касается производительности итерации в узле, а не что-то связанного с 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 мс для итерации через такой массив на моем не впечатляющем компьютере. Фактически, независимо от того, что вы делаете с каждым элементом, скорее всего, потребуется больше времени, чем повторение через массив.

Если вы заметили определенное отставание в производительности, вы можете уточнить, отредактировав сообщение. В противном случае я бы посоветовал не беспокоиться об этом.

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

  • Нет связанных вопросов^_^