IndexedDB: как избежать ада обратных вызовов

У меня есть IndexedDB, которая локально кэширует данные с тремя свойствами a, b и c. a и b вместе образуют составной ключ, а c — это то, что мне нужно.

Теперь клиент получает от сервера список элементов, которые я хочу отобразить. Затем клиент должен найти (a,b) в IndexedDB и получить соответствие c, а затем хешировать c с помощью sha1 (используя Rusha, это уже работает нормально).

Для тех элементов, где sha1(c_client) не совпадает с sha1(c_server), клиент извлекает все пары (a,b) с сервера (используя один запрос GET с сериализованным JSON-массивом (a,b)). Сервер возвращает обновленное содержимое c, а затем клиент сохраняет новое значение c в IndexedDB, а затем передает весь массив объектов функции отображения.

Как видите, большая часть логики абсолютно нуждается в последовательных операциях, но IndexedDB сильно асинхронна.

Любой способ сделать то, что я хочу, синхронным способом?


person Skynet    schedule 23.01.2014    source источник
comment
Пока основные браузеры не реализуют генераторы ES6, просто синхронная запись невозможна. Лучше всего использовать библиотеку управления потоком, чтобы облегчить боль или программировать в асинхронном режиме. осведомленный расширенный набор Javascript, который компилируется в версию кода обратного вызова, например это   -  person hugomg    schedule 23.01.2014
comment
По сути, это потребует от меня обернуть весь API IndexedDB в оболочку async.js?   -  person Skynet    schedule 23.01.2014
comment
Нет, ваш код по-прежнему будет взаимодействовать с indexdBAPI через те же обратные вызовы, что и раньше. Разница в том, что эти инструменты позволяют вашему коду быть немного более организованным, вместо этого ">пирамида гибели шаблон вложенных обратных вызовов.   -  person hugomg    schedule 23.01.2014


Ответы (2)


Мой подход к обратным вызовам IndexedDB заключался в диспетчеризации событий с использованием шаблона публикации подписки. Вы можете написать свой собственный обработчик или использовать триггеры JQuery.

Что я сделал, так это сгруппировал все логические события IndexedDB, и когда произойдет обратный вызов IndexedDB, он уведомит издателя о том, какое событие произошло, и издатель уведомит все функции, ожидающие этого события.

Примеры событий, которые у меня есть: создана база данных, завершено индексирование, начата синхронизация, завершена синхронизация... У меня также есть события для хода синхронизации, которые используются для уведомления пользователя о ходе (я синхронизирую в пакетах).

Модель публикации-подписки позволила мне отделить код IndexedDB от кода пользовательского интерфейса и, таким образом, легко изменить код действий события или добавить больше слушателей к тому же событию. Если вам нужна последовательная функция, вы можете связать события в цепочку, когда одно из них завершится, чтобы запустить его, а следующее может продолжиться.

person Deni Spasovski    schedule 24.01.2014
comment
Шаблон Pubsub слишком развязан, что приведет к разбрызгиванию кода. Обещание или шаблон генератора * предпочтительнее для индексированного db api. - person Kyaw Tun; 25.01.2014
comment
Привет, Чжоу. Я согласен с тем, что шаблон обещания является лучшим подходом для цепочки событий, однако в моем случае он хорошо работает с шаблоном pubsub, поскольку я использую его для соединения различных логических объектов и у меня нет глубокой цепочки. - person Deni Spasovski; 27.01.2014

Версия API IndexedDB для синхронизации была заброшена до того, как спецификация была завершена, поэтому вам всегда придется работать асинхронно.

Меня также раздражал API, поэтому я создал простую оболочку под названием db.js, которая использует промисы для запрос. Если вам посчастливилось ориентироваться только на платформу, поддерживающую генераторы, вы можете объединить их с db.js для сделать его более синхронным.

person Aaron Powell    schedule 29.01.2014