React Native计算繁重的任务

时间:2017-03-14 15:16:09

标签: asynchronous react-native realm background-process redux-observable

非常简单和常见的用例,但我找不到令人满意的答案。 我已经做出反应原生应用,需要在本地存储一些数据。我使用redux和redux-observables以及Realm作为存储。

我需要的是:发生一些动作,让我们说ADD_ITEM。我需要使用一些有效负载(标准redux)更新UI。然后我想创建/转换该有效负载到另一个数据并将该数据保存到Realm(异步)。无论我尝试什么,它总是滞后于UI(很多)。

我尝试将该域调用包装成promise并使用switchMap,但它仍然很慢。

我还没看过工人,但是他们只接受字符串,这对我来说更不用了。

我可以将该计算完全卸载到本机后台线程,但这将非常不舒服并且需要大量编写。

异步等待帮助我吗? redux-saga?我觉得它是一样的,而不是真正的异步处理。

或者我使用完全错误的库?

const insertOrderItem = (action$) =>
    action$.ofType(Action.ADD_ORDER_ITEM)
        .switchMap(({ payload }) => Rx.Observable.fromPromise(
            new Promise((resolve, reject) => {
                storage.insert(createObject(payload)
                resolve({
                    type: "OPERATION_ADDED"
                })
            })
        ))

一般来说,将小块数据存储到领域不应该是计算量很大但我觉得在后台线程上做这类工作是必要的。

我错过了什么吗?

由于

3 个答案:

答案 0 :(得分:4)

我的应用程序使用React Native + Realm DB遇到了同样的问题。我尝试了各种方法,无需编写本机代码,并将反应原生桥本地化为本机,最后我找到了解决方案:

https://corbt.com/posts/2015/12/22/breaking-up-heavy-processing-in-react-native.html

  1. 安装npm install next-frame --save
  2. 将下一帧添加到代码import nextFrame from 'next-frame';
  3. 在for long中添加此行,或在DB await nextFrame();
  4. 中插入for

    完整的示例如下所示:

    import nextFrame from 'next-frame';
    
    let response = await fetch("https://emberall.com/user/1/recordings");
    let responseJSON = await response.json();
    
    for (let recording of responseJSON.recordings) {
      await nextFrame(); // The javascript will yield here and not resume execution until the next frame. 
      mergeRecordingToLocalDatabase(recording);
    }
    

    基本上它的作用是在每次迭代或db-insert中等待JS渲染和处理下一个UI框架,这样你的应用程序就不会卡住或冻结。

    P.P。:我知道自问题已经过去了好几个月,但我认为很多人都可以从中受益。

答案 1 :(得分:2)

由于JS在一个线程中运行,所以它很滞后。因此,如果您将代码包装在Promise中,它仍然在一个线程中。

我认为最好的解决方案是通过React Native网桥将数据传输到本机,并在本机代码中进行此转换。 For guide how to communicate with native code look here

答案 2 :(得分:0)

我不熟悉Realm,但我似乎无法找到您正在使用的storage.insert API。我只看到realm.write()次交易。我试图看看他们是否有一个真正的非阻塞的异步API,但看起来Realm没有为他们的JavaScript绑定提供一个。

他们似乎在使用executeTransactionAsync()的Java绑定中提供了非阻塞API,但这不太适合您。

看起来你的选择似乎是:在另一个线程上使用本机执行,或者如何减少写入开销(较小的对象,在不明显的时候写入等)