使用 React 获取 Web Worker

Sea*_*ean 6 javascript fetch web-worker reactjs

我有一个 React 页面,它要求用户输入一些信息并从 API 返回一组 JSON 对象。

该查询可能会返回一个很大的结果,导致页面在加载 fetch 时冻结,所以我想使用 web worker 来分离线程并添加一个加载轮来让用户知道站点没有崩溃。

我目前有我的网络工作者使用以下代码:

工人代码

const self = this;

export default () => {
    self.addEventListener('message', e => {
        if (!e) return;
        let query = e.data;
        let res = null;

        fetch(`https://statsapi.web.nhl.com/api/v1/schedule?startDate=${query}&endDate=${query}`)
        .then(response => {
            return response.json();
        })
        .then(function(_ref) {
            postMessage(_ref);
        });
    });
}; 
Run Code Online (Sandbox Code Playgroud)

这只是一个示例 API,但真正的 API 结果会更大,加载时间也更长。

我也在使用function(_ref)而不是({ data }) =>因为当通过 babel 处理时,当没有数据访问器通过 ref 时({ data }) =>会变成_ref.data,并_ref在返回数组时工作。

我在一个 web worker 类中实现了我的代码,如下所示:

工人构造函数

export default class WebWorker {
    constructor(worker) {
        const code = worker.toString();
        const blob = new Blob(['(' + code + ')()'], { type: 'text/javascript' });
        return new Worker(URL.createObjectURL(blob));
    }
}
Run Code Online (Sandbox Code Playgroud)

我在另一个班级中这样称呼网络工作者:

创建 Web Worker

componentDidMount = () => {
    this.worker = new WebWorker(worker);
}

getInfo = () => {
    this.worker.postMessage(this.state.query);

    this.setState(prevState => ({
        ...prevState,
        open: true
    }), () => {
        this.worker.addEventListener('message', (event) => {
            const res = event.data;
            this.setState({
                results: res,
                open: false
            });
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,当我尝试像我一样调用它时,网络工作者似乎没有在另一个线程上处理。即使 web worker 正在获取数据,页面仍然冻结,因为它在冻结后仍然正确设置状态。

我是网络工作者的新手,所以我是否缺少一些可以让它工作的东西,或者是否有不同的方式使用网络工作者进行提取?

Jac*_*cob 6

如果您的页面变得无响应,则表明主处理线程受到 CPU 密集型操作的影响。I/O-bound 操作,比如从 URL 获取,不会影响页面的响应能力,除了来自响应的一些解析开销。因此,worker 的最佳用法是在不同的线程上执行 CPU 密集型操作。在将 I/O 操作转移到工作人员时,您几乎没有(如果有的话)性能方面的收益。

最有可能的是,您的渲染逻辑或数据处理是导致事情挂起的原因,而不是网络请求处理。