【发布时间】:2018-09-17 16:57:02
【问题描述】:
我有一个 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);
});
});
};
这只是一个示例 API,但真正的 API 结果会更大并且需要更长的时间来加载。
我也使用function(_ref)而不是({ data }) =>,因为当通过babel处理时,({ data }) =>会在没有通过ref的数据访问器时变成_ref.data,而_ref用于返回数组。
我的代码在这样的网络工作者类中实现:
工人构造函数
export default class WebWorker {
constructor(worker) {
const code = worker.toString();
const blob = new Blob(['(' + code + ')()'], { type: 'text/javascript' });
return new Worker(URL.createObjectURL(blob));
}
}
我这样称呼另一个班级的网络工作者:
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
});
});
});
}
我遇到的问题是当我尝试像我一样调用它时,网络工作者似乎没有在另一个线程上处理。即使网络工作者正在获取数据,页面仍然会冻结,因为它在冻结后仍然正确设置状态。
我是网络工作者的新手,所以我是否遗漏了一些可以让它工作的东西,或者是否有不同的方式来使用网络工作者和获取?
【问题讨论】:
-
如果 JSON 数据很多,您可能会遇到序列化/反序列化的成本,因为这是一个 CPU 密集型操作。
-
(遗憾的是,共享数组缓冲区仅适用于 Chrome。caniuse.com/#feat=sharedarraybuffer)
-
你有没有机会为此使用 Create React App? CRA 在使用网络工作者时存在已知问题。
-
是的,我正在使用 Create React App
标签: javascript reactjs fetch web-worker