1.0.4 • Published 4 years ago
ray-worker v1.0.4
ray-worker
install
npm i --save ray-worker
props
params | type | default | descr |
---|---|---|---|
children | node or func | - | 内容区,自定义 worker接收展示, func: (workerState) => {} |
workerRes | string or func | - | 创建worker,当为 string时,表示 worker 路径,当为 function时,可将整个worker包装进一个 function进行创建 |
options | object | - | worker参数,如: { name: 'myworker' } |
worker | object | - | 自定义 Worker 实例,如:采用 worker-loader 加载worker时,可创建后传递 |
parser | func | - | data 解析器,解析从 Worker 中收到的message |
onMessage | func | - | 处理从 worker 接收到的消息数据 |
onError | func | - | worker错误处理 |
serializer | func | v => v | 序列化或者处理发送至 worker 的数据, 在 手动调用 postMessage 之后处理data |
forceMessage | bool | false | 强制接收消息,即:即使dom没有加载完成,也接收 worker 消息 |
preventWorker | bool | - | 不给 children 注入 worker 的属性,当采用 ref 方式处理worker时,可以设置为 true |
注意: 默认情况下,只有 dom 加载完成之后,才接收 worker 中的消息,如果 设置
forceMessage
为true
时,则只要 worker 创建,则可接收。
workerstate
params | type | default | descr |
---|---|---|---|
messages | array | [] | 从worker中接收到的所有的数据日志,{ data, date } |
errors | array | [] | 从worker中接收到的所有的错误信息,{ error, date } |
data | any | undefined | 从worker中接收到的数据,最新数据 |
error | any | undefined | 从worker中接收到的错误信息,最新错误信息 |
updateTime | Date | undefined | 更新日期,worker发送数据或错误时的当前日期 |
lastPostTime | Date | undefined | 最后一次发送向worker数据的日期 |
postMessage | func: (data) => {} | - | 向 worker 发送消息 |
注意: 默认在
componentWillUnmount
中执行了worker.terminate
,同时向worker
发送了type = 'CLOSED'
的数据,用于告知worker执行关闭。如果需要关闭 worker,则自行在worker中进行处理,如:
worker.js
self.addEventListener('message', e => {
if (!e) {
return;
}
let data = e.data;
if (data && data.type === 'CLOSED'){
self.close(); // Terminates the worker.
}
console.log('Received msg from UI:', data);
postMessage(data + random());
});
USAGE
- basic
app.js
import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';
/**
* 采用直接导入 worker 的方式
*
* @class WorkerDemo
* @extends {Component}
*/
class WorkerDemo extends Component {
render() {
return (
<RWorker workerRes="/demo1.js">
{({ data, error, postMessage, updatedAt, lastPostTime }) => (
<div className="worker-msg-box">
{data && (
<div>
<strong>[采用普通loader进行]Received some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
<Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
</div>
)}
</RWorker>
);
}
}
WorkerDemo.propTypes = {};
export default WorkerDemo;
demo1.js (worker)
function random() {
const i = Math.random() * 100 + 1;
return `ilex- ${parseInt(i)}`;
}
self.addEventListener('message', e => {
if (!e) {
return;
}
let data = e.data;
console.log('Received msg from UI:', data);
postMessage(data + random());
});
- use normal module
将 worker 作为一个 function 进行
app.js
import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';
import demo from './demo';
/**
* 采用 模块加载的方式
*
* @class WorkerDemo
* @extends {Component}
*/
class WorkerDemo extends Component {
render() {
return (
<RWorker workerRes={demo}>
{({ data, error, postMessage, updatedAt, lastPostTime }) => (
<div className="worker-msg-box">
{data && (
<div>
<strong>Received some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
<Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
</div>
)}
</RWorker>
);
}
}
WorkerDemo.propTypes = {};
export default WorkerDemo;
demo.js (worker)
export default () => {
function random() {
const i = Math.random() * 100 + 1;
return `ilex- ${parseInt(i)}`;
}
self.addEventListener('message', e => {
if (!e) {
return;
}
let data = e.data;
console.log('Received msg from UI:', data);
postMessage(data + random());
});
};
- worker-loader
app.js
import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Button from './Button';
import Worker from './demo.worker.js';
/**
* 采用 worker loader 方式
*
* @class WorkerLoaderDemo
* @extends {Component}
*/
class WorkerLoaderDemo extends Component {
constructor(props) {
super(props);
this.worker = new Worker();
}
render() {
return (
<RWorker worker={this.worker}>
{({ data, error, postMessage, updatedAt, lastPostTime }) => (
<div className="worker-msg-box">
{data && (
<div>
<strong>[采用worker-loader进行]Received some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
<Button updatedAt={updatedAt} lastPostTime={lastPostTime} postMessage={postMessage} />
</div>
)}
</RWorker>
);
}
}
WorkerLoaderDemo.propTypes = {};
export default WorkerLoaderDemo;
demo.worker.js (worker)
worker 中可以采用 es6 模块
import { random } from './_third';
// function random() {
// const i = Math.random() * 100 + 1;
// return `ilex- ${parseInt(i)}`;
// }
self.addEventListener('message', e => {
if (!e) {
return;
}
let data = e.data;
if (data && data.type === 'CLOSED'){
self.close(); // Terminates the worker.
}
console.log('Received msg from UI:', data);
postMessage(data + random());
});
扩展
- DataPane
- Pending
- WError
使用datapane, app.js
import React, { Component } from 'react';
import RWorker from 'ray-worker';
import Worker from './inner.worker.js';
const { Pending, DataPane, WError } = RWorker;
/**
* 采用 worker loader 方式
*
* @class WorkerInnerDemo
* @extends {Component}
*/
class WorkerInnerDemo extends Component {
constructor(props) {
super(props);
this.worker = new Worker();
}
render() {
return (
<RWorker worker={this.worker}>
<DataPane>
{
(data, workerState) => (
<div className="worker-msg-box">
<div>auto data:{data}</div>
<div className="all-msg">
<p>所有数据</p>
{JSON.stringify(workerState)}
</div>
</div>
)
}
</DataPane>
</RWorker>
);
}
}
WorkerInnerDemo.propTypes = {};
export default WorkerInnerDemo;
inner.worker.js (worker)
import { random } from './_third';
self.addEventListener('message', e => {
if (!e) {
return;
}
let data = e.data;
if (data && data.type === 'CLOSED'){
self.close(); // Terminates the worker.
}
console.log('Received msg from UI:', data);
postMessage(data + random());
});
postMessage(`auto data ${random()}`);
setInterval(() => {
postMessage(`auto data ${random()}`);
}, 2000);
WorkerPlugin
import React, { Component } from 'react';
import { WorkerPlugin } from 'ray-worker';
import demo from './workers/demo';
/**
* 采用 worker plugin
*
* @class WorkerDemo
* @extends {Component}
*/
class WorkerDemo extends Component {
constructor(props) {
super(props);
this.state = {
data: undefined
};
this.worker = new WorkerPlugin({
workerRes: demo,
onMessage: this.onMessage
});
}
componentWillUnmount() {
this.worker.destroy();
}
onMessage = (data) => {
this.setState({
data
});
}
onClick = () => {
this.worker.postMessage('hello');
}
render() {
const { data } = this.state;
return (
<div className="worker-msg-box">
{data && (
<div>
<strong>Received some data:</strong>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
)}
<div className="action-button">
<button onClick={this.onClick}>发送消息</button>
</div>
</div>
);
}
}
WorkerDemo.propTypes = {};
export default WorkerDemo;
- params
{
workerRes: 'string|func',
options: 'object',
worker: 'any',
parser: 'func',
onMessage: 'func',
onStateChange: 'func',
serializer: 'func',
onError: 'func'
}
- methods
postMessage()
getWorkerState()
destroy()
UIWorkerFactory
自行处理 主线程 worker UI
import React, { Component } from 'react';
import { UIWorkerFactory } from 'ray-worker';
import Worker from './workers/inner.worker.js';
/**
* 采用 worker loader 方式
*
* @class NonUIWorkerDemo
* @extends {Component}
*/
class NonUIWorkerDemo extends Component {
constructor(props) {
super(props);
this.worker = new Worker();
this.uiWorkerFactory = new UIWorkerFactory({
worker: this.worker,
onMessage: this.onMessage,
onError: this.onError
});
this.state = {
messages: [],
msg: ''
};
}
onMessage = (msg) => {
this.setState(prevState => ({
messages: [
...prevState.messages,
msg
],
msg
}));
}
onError = (err) => {
console.log(err);
}
render() {
return (
<div className="worker-msg-box">
<div>current message:{this.state.msg}</div>
<div className="all-msg">
<p>所有数据:</p>
{JSON.stringify(this.uiWorkerFactory.workerState, null, 2)}
</div>
</div>
);
}
}
NonUIWorkerDemo.propTypes = {};
export default NonUIWorkerDemo;
注意
当 children
为function时,参数为 RayWorker
整个 state;
当为 普通react组件时,默认注入 RayWorker
整个state
其它情况,如果要使用 RayWorker
state,则可以使用 getWorkerState
方法获取。
import RWorker from 'ray-worker';
const workerState = this.rworkerRef.getWorkerState();
<RWorker ref={node => this.rworkerRef = node}>
Lecense
MIT