Flux waitFor() 和异步操作,如何建模。

7
我正在使用PouchDB作为应用程序的本地数据库。 我想查询PouchDB的结果并将其加载到React.js中。 但是,即使我使用waitFor()方法,PouchDB查询结果返回得太晚了。 我认为我没有正确理解waitFor()的用途,也许有人可以帮忙解释一下。
我有两个存储库。 DbStore从数据库检索数据。 FileExplorerStore这个存储库由我的React组件使用。
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的函数,它会将DB文件加载到_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函数将调用FileExplorerStore中的getFiles()函数来显示文件。
如何修复这个问题或以更好的方式建模?
1个回答

9
由Facebook团队发布的dispatcher中的waitFor并不是为此设计的(至少在2014年9月11日发布的版本中),它只确保传递给waitFor函数的dispatchToken得到执行并返回后,才会开始执行下一个注册的回调函数。
因此,在您的情况下,这在某种程度上是正确的预期行为。
我的建议是将操作分为两部分。第一部分是获取数据,第二部分是打开文件夹(如FileExplorerStore中的OPEN_FOLDER)。假设DBfetch操作被命名为DB_FETCH,则这将触发数据库并将数据存储在_files变量中。在获取成功的回调函数中,触发一个名为“action”的OPEN_FOLDER操作。关于触发点,取决于您如何设计它,我可能会使用第三个动作命名为INIT_OPEN_FOLDER,它将触发DB_FETCH,然后向UI显示加载指示器,并最终在从OPEN_FOLDER接收到emit后仅显示数据。

谢谢。看起来你的解释是正确建模的正确方式。我还查看了#reactjs IRC,他们也建议在我的异步获取回调中调用一个操作。然而,我改用了Reflux,因为在Reflux中,我可以从操作中调用我的数据库API,并在数据获取后执行下一个操作。 - swennemen
@ChinKang,请看这里https://dev59.com/fo_ea4cB1Zd3GeqPJAoq - VB_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接