2013-11-30 4 views
3

У меня есть следующий запрос:Прогресс событий для больших запросов Firebase?

fire = new Firebase 'ME.firebaseio.com' 
users = fire.child 'venues/ID/users' 
users.once 'value', (snapshot) -> 
    # do things with snapshot.val() 
    ... 

Я ЗАГРУЗКА 10+ Мб данных, и запрос занимает около 1сек/мб. Можно ли дать пользователю индикатор прогресса в потоках контента? В идеале я хотел бы обрабатывать данные так же хорошо (не просто уведомлять).

Я попытался использовать событие on "child_added" вместо этого, но он работает не так, как ожидалось. Вместо того, чтобы дети потоковали с постоянной скоростью, все они появляются сразу после загрузки всего набора данных (что занимает 10-15 секунд) , поэтому на практике это выглядит менее результативной версией on "value".

+0

Это правда, что child_added загружает исходный набор данных перед запуском событий. Есть несколько способов, которыми мы могли бы выполнить ваши цели здесь, но мне очень трудно понять пример использования, когда практически необходимо загрузить 10 МБ данных в браузер. Не могли бы вы рассказать о конечной цели, чтобы я мог лучше подобрать ответ на ваши нужды? – Kato

+0

Конечно! Мне нужно загрузить список пользователей в определенном месте для приложения присутствия в реальном времени, которое я создаю. Каждый список большой, а некоторые списки содержат небольшие изображения с кодировкой base64, что увеличивает размер файла. Мне нужно показать пользователю список пользователей как можно быстрее, поэтому подход на основе потоков будет идеальным здесь. Ожидание 10-20 секунд для загрузки полного набора данных нецелесообразно по причинам удобства использования. – bcherny

ответ

3

Вы должны быть в состоянии оптимизировать время загрузки от 10-20 секунд до нескольких миллисекунд, начиная с denormalization.

Например, мы могли бы перемещать изображения и любые другие периферийные устройства, содержащие большую часть полезной нагрузки, в свой собственный путь, хранить только метаданные (имя, адрес электронной почты и т. Д.) В пользовательских записях и отдельно приобретать дополнительные функции:

/users/user_id/name, email, etc... 
/images/user_id/... 

количество слушателей событий прикреплении или пути подключения к не имеет каких-либо значительных накладных расходов на местном уровне или для сетей полосы пропускания (только полезная нагрузка), так что вы можете сделать что-то вроде этого «нормализовать» после захвата мета данные:

var firebaseRef = new Firebase(URL); 
firebaseRef.child('users').on('child_added', function(snap) { 
    console.log('got user ', snap.name()); 

    // I chose once() here to snag the image, assuming they don't change much 
    // but on() would work just as well 
    firebaseRef.child('images/'+snap.name()).once('value', function(imageSnap) { 
     console.log('got image for user ', imageSnap.name()); 
    }); 
}); 

Вы сразу заметите, что, когда вы перемещаете основную часть данных и сохраняете только метаинформацию для пользователей локально, они будут молниеносно захватывать (все журналы журнала «got user» появятся сразу). Затем изображения будут просачиваться по одному за раз после этого, позволяя создавать полосы выполнения или обрабатывать их по мере их появления.

Если вы не хотите денормализовать данные, есть несколько способов разбить процесс загрузки. Вот простой pagination approach, чтобы захватить пользователей в сегментах:

var firebaseRef = new Firebase(URL); 
grabNextTen(firebaseRef, null); 

function grabNextTen(ref, startAt) { 
    ref.limit(startAt? 11 : 10).startAt(startAt).once('value', function(snap) { 
     var lastEntry; 
     snap.forEach(function(userSnap) { 
     // skip the startAt() entry, which we've already processed 
     if(userSnap.name() === lastEntry) { return; } 
     processUser(userSnap); 
     lastEntry = userSnap.name(); 
     }); 

     // setTimeout closes the call stack, allowing us to recurse 
     // infinitely without a maximum call stack error 
     setTimeout(grabNextTen.bind(null, ref, lastEntry); 
    }); 
} 

function processUser(snap) { 
    console.log('got user', snap.name()); 
} 

function didTenUsers(lastEntry) { 
    console.log('finished up to ', lastEntry); 
} 

Третий популярный подход будет хранить изображения в статическом облаке актива, как Amazon S3 и просто хранить URL-адреса в Firebase. Для больших наборов данных в сотнях тысяч это очень экономично, поскольку эти решения немного дешевле, чем хранилище Firebase.

Но я бы очень хотел, чтобы вы оба прочитали статью о денормализации и сначала инвестируете в этот подход.

+0

Спасибо за подробный ответ! Подход с разбивкой по страницам выглядит так, как мне нужно - я попробую и отправлю отчет. Большая часть полезной нагрузки для каждого пользователя - это метаданные, которые было бы неудобно денормализовать. Полезные грузы, содержащие изображения b64, действительно являются краеугольным камнем для меня, поскольку они не появляются очень часто. – bcherny

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