使用 Redux 的 Web-Worker Promise
Use Promises For Web-Worker With Redux
我的设置是:Webpack、React、Redux(包括 redux-thunk)。
我正在努力将网络工作者集成到我的 mouseMove
eventListener 中。需要找出当用户在绘图应用程序中绘制时哪些元素与 'group selection' 矩形发生冲突。
对 web-worker 的调用将是异步的,因此,在 action-creator 函数中,我试图提出一个承诺,该承诺在 resolve 时调用有效负载创建 func (resolve),如下所示:
动作创作者:
export const groupSelectionPayload = ( a, b, c ) => {
let something = doSomething( a, b );
return( new Promise( function( resolve, reject ){
let selectedElements = getSelectedElements( something, c );
// Im not sure about the below condition,
// which I am using to call either resolve / reject funcs,
// is there a better way to handle this?
if( selectedElements !== undefined ){
resolve( something );
} else {
reject();
}
}));
};
// when promise resolves, we return the action to dispatch
const resolve = function( rectCoOrd ){
return ({
type : CREATE_GROUP_SELECTION_RECT,
svgPayload : {
curToolbarCtrlSelection : {
ctrlName : "grpSelect",
props : {
pos : {
x : rectCoOrd[ 0 ],
y : rectCoOrd[ 1 ],
w : rectCoOrd[ 2 ],
h : rectCoOrd[ 3 ]
}
}
}
}
});
};
// func posts message to web-worker
const getSelectedElements = ( something, c ) => {
worker_handler.postMessage( iMap({
type : "grpSelect",
}));
};
我正在使用 Redux-thunk 进行异步处理,但是,我收到错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
其次是:
uncaught exception : undefined
我做错了什么,有没有更明智的方法来处理上面讨论的场景?
编辑:
我需要安装我拥有的 redux-promise 中间件。
const store = createStore( reducer, composeEnhancer( applyMiddleware( thunk, promiseMiddleware )));
... 解决了 Actions must be plain objects ...
错误。但是,我仍然收到 uncaught exception : undefined
错误。
嗯,我猜你的动作创建者应该是这样的:
export const groupSelectionPayload = ( a, b, c ) => dispatch => {
//do some async stuff like so:
new Promise((res, rej) => { … })
.then(data => dispatch({type: 'success', payload: { data }}))
.catch(error => dispatch({type: 'error', payload: { error }}))
}
Redux thunk 将使用 dispatch 作为参数调用创建者 returned 的方法。因此,在该方法中,您可以在异步操作完成时、之前或正在进行时分派其他操作。
此外,redux thunk 将 return 动作创建者提供的函数值。也可以:
const someAction = id => dispatch => new Promise((res, rej) => {
const result = something(id);
if (result !== null) {
dispatch({type: 'success', payload: { result }})
res(result);
} else { … }
});
并且在组件中你比:
this.props.action(<id>).then(/*getting fancy here, update State or something*/);
但是当你在处理 webWorker 时,我认为中间件是放置代码的更好地方:
const customMiddleware = store => {
//create and connect to the worker here
const worker = …
worker.onmessage = msg => store.dispatch({type: 'workermsg', payload: {msg}});
return next => action => {
if(action.type !== 'posttoworker') return next(action)
worker.postMessage(action.payload.msg)
}
}
我没有太在意worker代码,只是想把middle用作worker的api…
我的设置是:Webpack、React、Redux(包括 redux-thunk)。
我正在努力将网络工作者集成到我的 mouseMove
eventListener 中。需要找出当用户在绘图应用程序中绘制时哪些元素与 'group selection' 矩形发生冲突。
对 web-worker 的调用将是异步的,因此,在 action-creator 函数中,我试图提出一个承诺,该承诺在 resolve 时调用有效负载创建 func (resolve),如下所示:
动作创作者:
export const groupSelectionPayload = ( a, b, c ) => {
let something = doSomething( a, b );
return( new Promise( function( resolve, reject ){
let selectedElements = getSelectedElements( something, c );
// Im not sure about the below condition,
// which I am using to call either resolve / reject funcs,
// is there a better way to handle this?
if( selectedElements !== undefined ){
resolve( something );
} else {
reject();
}
}));
};
// when promise resolves, we return the action to dispatch
const resolve = function( rectCoOrd ){
return ({
type : CREATE_GROUP_SELECTION_RECT,
svgPayload : {
curToolbarCtrlSelection : {
ctrlName : "grpSelect",
props : {
pos : {
x : rectCoOrd[ 0 ],
y : rectCoOrd[ 1 ],
w : rectCoOrd[ 2 ],
h : rectCoOrd[ 3 ]
}
}
}
}
});
};
// func posts message to web-worker
const getSelectedElements = ( something, c ) => {
worker_handler.postMessage( iMap({
type : "grpSelect",
}));
};
我正在使用 Redux-thunk 进行异步处理,但是,我收到错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
其次是:
uncaught exception : undefined
我做错了什么,有没有更明智的方法来处理上面讨论的场景?
编辑: 我需要安装我拥有的 redux-promise 中间件。
const store = createStore( reducer, composeEnhancer( applyMiddleware( thunk, promiseMiddleware )));
... 解决了 Actions must be plain objects ...
错误。但是,我仍然收到 uncaught exception : undefined
错误。
嗯,我猜你的动作创建者应该是这样的:
export const groupSelectionPayload = ( a, b, c ) => dispatch => {
//do some async stuff like so:
new Promise((res, rej) => { … })
.then(data => dispatch({type: 'success', payload: { data }}))
.catch(error => dispatch({type: 'error', payload: { error }}))
}
Redux thunk 将使用 dispatch 作为参数调用创建者 returned 的方法。因此,在该方法中,您可以在异步操作完成时、之前或正在进行时分派其他操作。
此外,redux thunk 将 return 动作创建者提供的函数值。也可以:
const someAction = id => dispatch => new Promise((res, rej) => {
const result = something(id);
if (result !== null) {
dispatch({type: 'success', payload: { result }})
res(result);
} else { … }
});
并且在组件中你比:
this.props.action(<id>).then(/*getting fancy here, update State or something*/);
但是当你在处理 webWorker 时,我认为中间件是放置代码的更好地方:
const customMiddleware = store => {
//create and connect to the worker here
const worker = …
worker.onmessage = msg => store.dispatch({type: 'workermsg', payload: {msg}});
return next => action => {
if(action.type !== 'posttoworker') return next(action)
worker.postMessage(action.payload.msg)
}
}
我没有太在意worker代码,只是想把middle用作worker的api…