简体   繁体   English

在 React 中使用共享 Worker

[英]Using Shared Worker in React

I have a backend app that constantly serves events to my React app via Web Sockets. When a specific event is received a new browser tab should be opened.我有一个后端应用程序,它通过 Web Sockets 不断向我的 React 应用程序提供事件。当收到特定事件时,应该打开一个新的浏览器选项卡。 The application will be run by a user in multiple tabs, so I need to open a new tab only once and prevent it from being opened by all running instances.该应用程序将由用户在多个选项卡中运行,因此我只需要打开一个新选项卡一次并防止它被所有正在运行的实例打开。

I've tried using Redux persistent storage, but it doesn't seem to correspond my needs.我试过使用 Redux 持久存储,但它似乎不符合我的需求。 The best solution that I've found is Shared Workers.我发现的最佳解决方案是 Shared Workers。

I've tried using Shared Worker in my React app, but I can't set up it properly.我试过在我的 React 应用程序中使用 Shared Worker,但我无法正确设置它。 It's either being imported incorrectly or Webpack is unable to load it Uncaught SyntaxError: Unexpected token <它要么导入不正确,要么 Webpack 无法加载它Uncaught SyntaxError: Unexpected token <

When I googled I haven't found any examples of using Shared Worker in React app (with or without CRA) and at this point, I'm not even sure it's possible.当我用谷歌搜索时,我没有找到任何在 React 应用程序(有或没有 CRA)中使用 Shared Worker 的例子,在这一点上,我什至不确定它是否可能。 I did found some Web Workers examples, but they have totally different configs.我确实找到了一些 Web Workers 示例,但它们的配置完全不同。

Can anyone please share some specifics of running Shared Worker in React?任何人都可以分享一些在 React 中运行 Shared Worker 的细节吗? Or any other ideas that can provide me with similar functionality will be also greatly appreciated.或者任何其他可以为我提供类似功能的想法也将不胜感激。

Edit: Adding lastest code of what I've tried.编辑:添加我尝试过的最新代码。 Disregard the counter logic, consider just the setup:忽略计数器逻辑,只考虑设置:

worker.js工人.js

import React from 'react';

export const startCounter = () => {
  window.self.addEventListener("message", event => {
    console.log(event.data, self);
    let initial = event.data;
    setInterval(() => this.postMessage(initial++), 1000);}); 
}

App.js应用程序.js

import React, { Component } from 'react';
import {startCounter} from './worker';

class App extends Component {

  componentDidMount() {
    const worker = new SharedWorker(startCounter);
    worker.port.start()
    // worker.postMessage(this.state.counter);
    // worker.addEventListener('message', event => this.setState({counter: event.data}));
  }

  render() {
    return (
      <div className="App">
      </div>
    );
  }
}

export default App;

make a file called WebWorker.js which looks like this: 制作一个名为WebWorker.js的文件,如下所示:

export default class WebWorker {
    constructor(worker) {
        const code = worker.toString();
        const blob = new Blob(['('+code+')()']);
        return new SharedWorker(URL.createObjectURL(blob));
    }
}

and import it to your main file and do this: 并将其导入到您的主文件中,然后执行以下操作:

const workers = new WebWorker(worker);
 workers.postMessage(some message);

Clarifying @Birat's answer: The SharedWorker constructor is looking for a URL , but here you're passing it a function:澄清@Birat 的回答:SharedWorker 构造函数正在寻找 URL ,但在这里您传递给它的是 function:

    const worker = new SharedWorker(startCounter);

Give this a try instead:试试这个:

    const worker = new SharedWorker(new URL('./worker', import.meta.url));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM