微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用React,Typescript和Mobx实现Web Worker?

如何解决如何使用React,Typescript和Mobx实现Web Worker?

我有一个mobx存储区(admisionStore),其中包含操作和可观察对象,其中一些操作是使用Axios从API加载数据的,但是这是一项长期运行的任务,它会使UI变慢,我了解到Web worker可能是在这种情况下很有帮助。

我遵循了本文的指南:https://dev.to/nicolasrannou/web-workers-in-create-react-app-cra-without-unmounting-4865,这就是我所拥有的:

//typings-custom/custom.d.ts

declare module 'worker-loader!*' {
  class WebpackWorker extends Worker {
    constructor();
  }

  export default WebpackWorker;
}
//worker.ts

import {expose} from 'comlink';
export interface WorkerType {
  busy(value: number): number;
}

const obj: WorkerType = {
  busy(value: number) {
    let j = 0;
    const start = Date.Now();

    for (let i = 0; i < value; i++) {
      //
      j++;
      const end = Date.Now();
      // if it has been busy for more than 10s return
      if (end - start > 10000) {
        return i;
      }
    }
    return j;
  },};

expose(obj);
//App.tsx

import React from 'react';
import {wrap} from 'comlink';
/* eslint-disable import/no-webpack-loader-Syntax */
import Worker from 'worker-loader!./worker';
import { WorkerType } from './worker';

const handle = async () => {
startDummyWorker()
};

async function startDummyWorker() {
  const worker = new Worker();
  const obj = wrap<WorkerType>(worker);
  const finished = await obj.busy(10000000000000000000);
  console.log(finished);
}

const App = () => {
  return (
    <div>
      <button onClick={handle}>Press</button>
      <button onClick={() => console.log('HOLA')}>press2</button>
    </div>
  );
};

export default App;

//webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.worker\.(js|ts)$/i,use: [
          {
            loader: 'worker-loader',},],};

如您所见,我必须为Typescript以及接口WorkerType创建类型声明文件,否则Typescript会抱怨,我还创建了webpack.config.js文件以配置worker-loader: https://webpack.js.org/loaders/worker-loader/#config

一切正常,但是当我试图在React中使用mobx作为状态管理来实现这种方法时,它没有用。这是我的代码

//worker.ts

import { expose } from 'comlink';
import { useContext } from 'react';
import { RootStoreContext } from '../app/stores/rootStore';
export interface WorkerType {
  load(): void;
}

const rootStore = useContext(RootStoreContext);
const { loadAsegurado } = rootStore.admisionStore;

const admisionWorker: WorkerType = {
  load() {
    loadAsegurado; //mobx action loadAsegurado: () => Promise<void>
  },};
expose(admisionWorker);
//AdmisionDashboard.tsx
import React,{ useContext,useEffect} from 'react';
import { observer } from 'mobx-react-lite';
import { RootStoreContext } from '../../../../app/stores/rootStore';
import { wrap } from 'comlink';
/* eslint-disable import/no-webpack-loader-Syntax */
import Worker from 'worker-loader!../../../../my-first-worker/worker';
import { WorkerType } from '../../../../my-first-worker/worker';

function startAdmisionWorker() {
  const worker = new Worker();
  const workerApi = wrap<WorkerType>(worker);
  workerApi.load();
}

const AdmisionDashboard=()=>{
const rootStore = useContext(RootStoreContext);
const {loadAsegurado,setoperacion} = rootStore.admisionStore
const { token } = rootStore.commonStore;

useEffect(() => {
    if (token === null) {
      history.push('/');
    } else {
      setoperacion('buscar');
      startAdmisionWorker();//Here I start my web worker
    }
  },[setoperacion,token]);

[...] // rest of the code
}
export default observer(AdmisionDashboard);

启动应用程序时,我收到以下日志:

Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.

C:\Users\Desarrollo\Desktop\NHME-app>npm start

> admision-app@0.1.0 start C:\Users\Desarrollo\Desktop\NHME-app
> react-scripts start

Starting the development server...


<--- Last few GCs --->

[12160:0000007516C6E060]   265687 ms: Scavenge 2006.3 (2067.4) -> 1992.7 (2068.2) MB,38.8 / 0.1 ms  (average mu = 0.260,current mu = 0.315) allocation failure
[12160:0000007516C6E060]   268205 ms: Mark-sweep 2010.8 (2071.5) -> 1993.4 (2068.1) MB,2315.7 / 0.4 ms  (average mu = 0.224,current mu = 0.184) allocation failure scavenge might not succeed


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 00007FF69AC6463D]
Security context: 0x02baba3008a1 <JSObject>
    1: /* anonymous */ [000002B6DF429F31] [C:\Users\Desarrollo\Desktop\NHME-app\node_modules\webpack\node_modules\acorn\dist\acorn.js:~2945] [pc=0000017352FE77BB](this=0x0282de28a389 <Parser map = 0000010C5D327E41>)
    2: /* anonymous */ [000002B6DF428BB1] [C:\Users\Desarrollo\Desktop\NHME-app\node_modules\webpack\node_modules\acorn\dist\acorn.js:1155] [b...

Fatal error: Ineffective mark-compacts near heap limit Allocation Failed - JavaScript heap out of memory

Writing Node.js report to file: report.20200828.085936.12160.0.001.json
Node.js report completed
 1: 00007FF69A09232F napi_wrap+124543
 2: 00007FF69A0336A6 public: bool __cdecl v8::base::cpu::has_sse(void)const __ptr64+34502
 3: 00007FF69A034366 public: bool __cdecl v8::base::cpu::has_sse(void)const __ptr64+37766
 4: 00007FF69A838C5E private: void __cdecl v8::Isolate::ReportExternalAllocationLimitReached(void) __ptr64+94
 5: 00007FF69A820CA1 public: class v8::SharedArrayBuffer::Contents __cdecl v8::SharedArrayBuffer::Externalize(void) __ptr64+833
 6: 00007FF69A6EE56C public: static void __cdecl v8::internal::Heap::EphemeronKeyWriteBarrierFromCode(unsigned __int64,unsigned __int64,class v8::internal::Isolate * __ptr64)+1436
 7: 00007FF69A6F9910 public: void __cdecl v8::internal::Heap::ProtectUnprotectedMemoryChunks(void) __ptr64+1312
 8: 00007FF69A6F6444 public: static bool __cdecl v8::internal::Heap::PageFlagsAreConsistent(class v8::internal::HeapObject)+3204
 9: 00007FF69A6EBCD3 public: bool __cdecl v8::internal::Heap::CollectGarbage(enum v8::internal::AllocationSpace,enum v8::internal::GarbageCollectionReason,enum v8::GCCallbackFlags) __ptr64+1283
10: 00007FF69A6EA4A4 public: void __cdecl v8::internal::Heap::AddRetainedMap(class v8::internal::Handle<class v8::internal::Map>) __ptr64+2356
11: 00007FF69A70B775 public: class v8::internal::Handle<class v8::internal::HeapObject> __cdecl v8::internal::Factory::NewFillerObject(int,bool,enum v8::internal::AllocationType) __ptr64+53
12: 00007FF69A477A49 ??4iterator@JumpTableTargetoffsets@interpreter@internal@v8@@QEAAAEAV01234@$$QEAV01234@@Z+4057
13: 00007FF69AC6463D public: virtual bool __cdecl v8::internal::SetupIsolateDelegate::SetupHeap(class v8::internal::Heap * __ptr64) __ptr64+567949
14: 0000017352FE77BB
npm ERR! code ELIFECYCLE
npm ERR! errno 134
npm ERR! admision-app@0.1.0 start: `react-scripts start`
npm ERR! Exit status 134
npm ERR!
npm ERR! Failed at the admision-app@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Desarrollo\AppData\Roaming\npm-cache\_logs\2020-08-28T14_59_37_653Z-debug.log

C:\Users\Desarrollo\Desktop\NHME-app>

任何建议将不胜感激。预先感谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。