Flux waitFor() и асинхронная операция, как моделировать.

Я использую pouchDB в качестве локальной базы данных для приложения. Я хочу запросить результаты из PouchDB и загрузить их в React.js. Однако, несмотря на то, что я использую метод waitFor(), результаты запроса PouchDB возвращаются слишком поздно. Я думаю, что не понимаю правильное использование waitFor(), может быть, кто-то может пролить на это свет.

У меня есть два хранилища: DbStore, который извлекает данные из базы данных. И это хранилище FileExplorerStore используется моими реагирующими компонентами.

DbStore.dispatchToken = AppDispatcher.register(function (payload) {

    var action = payload.action;
    var folder = payload.action.folder
    switch (action.type) {

        case 'OPEN_FOLDER':    
            if (folder === 'start') {
                DbStore.init();
            }
            else {
                DbStore.createPath(folder);
            }
            DbStore.emitChange();
            break;
        default:
        // do nothing
    }


    return true;
});

В DbStore есть функция LoadFiles, которая загружает файлы БД в массив _files. Для наглядности я скопировал код ниже:

loadFiles: function (_path) {
            var fileNames = fs.readdirSync(_path);
            _files = [];


            fileNames.forEach(function (file) {
                console.log(file)
                db.query(function (doc) {
                    emit(doc.name);
                }, {key: "bower.json"}).then(function (res) {
                    _files.push(res.rows[0].key)
                });
            });

 }, 

У FileExplorerStore был метод для извлечения файлов из массива _files. Затем в FileExplorerStore у меня есть метод getFiles(), который извлекает эти файлы. Однако этот массив всегда пуст, поскольку этот метод будет выполнен до того, как массив будет заполнен.

FileExplorerStore

FileExplorerStore.dispatchToken = AppDispatcher.register(function (payload) {

var action = payload.action;


switch (action.type) {

    case 'OPEN_FOLDER':
        AppDispatcher.waitFor([DbStore.dispatchToken]);

        FileExplorerStore.emitChange();
        break;
    default:
    // do nothing
}


return true;
});

В react.js функция getInitialState будет вызывать функцию getFiles() из FileExplorerStore для отображения файлов.

Как я могу исправить это или смоделировать это лучше?


person swennemen    schedule 05.01.2015    source источник


Ответы (1)


waitFor в dispatcher, выпущенном командой Facebook, не предназначено для этого (по крайней мере, выпуск от 11 сентября 2014 г.), он просто обеспечивает выполнение и возврат dispatchToken (который перешел к waitFor), а затем он начнет выполняться. следующий зарегистрированный обратный вызов.

Так что в вашем случае это как-то правильное ожидаемое поведение.

Что я сделаю, так это разделю действие на две части. Первый - получение, второй - OPEN_FOLDER как в FileExplorerStore. Предполагая действие DBfetch с именем DB_FETCH, это активирует вашу базу данных, а затем получит данные в _files, в обратном вызове успеха выборки вызовет action в OPEN_FOLDER. Что касается точки срабатывания, это зависит от вас, как вы хотите ее спроектировать, у меня было бы третье действие с именем INIT_OPEN_FOLDER, которое запускает DB_FETCH, затем показывает индикатор загрузки в пользовательском интерфейсе и, наконец, когда получает выброс от OPEN_FOLDER, только отображает данные

person ChinKang    schedule 06.01.2015
comment
Спасибо. Похоже, ваше объяснение - правильный способ смоделировать это. Я также проверил #reactjs IRC, и они также советуют вызывать действие в моем обратном вызове асинхронной выборки. Однако я перешел на Reflux, потому что в Reflux я могу вызывать свой API базы данных из действий и после извлечения данных выполнять следующее действие. - person swennemen; 06.01.2015
comment
@ChinKang, не могли бы вы посмотреть здесь, пожалуйста, stackoverflow.com/questions/32537568/< /а> - person VB_; 12.09.2015