使用承诺为网络工作者终极版
问题描述:
我的设置是:的WebPack,反应,终极版(含终极版-的thunk)。使用承诺为网络工作者终极版
我正在朝着我mouseMove
事件监听整合网络工作者。当用户在绘图应用程序中绘制时,需要找出哪些元素与'组选择'直接碰撞。
到网络工作者的通话将是异步的话,动作创造者函数中,我尝试如下,以提高一个承诺,它在解析后,调用负载创建FUNC(解析):
ACTION CREATOR:
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",
}));
};
我使用的终极版,为的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 }}))
}
终极版的thunk会调用该方法从和讯作为参数的创建者返回。因此,在该方法中,您可以调度其他操作,异步操作完成后或之前或正在进行时。
此外终极版形实转换将返回由动作建立者所提供的功能的值。所以还可以:
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)
}
}
我并没有太在意工人代码,它只是想法,使用中间为工人的API ...
这是一个很好的答案,对我来说很重要。我不需要网络工作者来完成所有任务,因此不会考虑将它作为中间件集成。另外,我可能需要多个网络工作者来完成不同的任务,例如元素之间的碰撞,当用户添加了新的元素已填写元素(检查元素的坐标对几千个元素被重)以帆布... – Kayote
我想你missunderstood中间件的概念了一下。有了它,你就可以订阅某些感兴趣的动作,所有其他人都可以通过。基本上你可以为每个工人提供一个中间件。 – philipp
那我当然做到了。我实际上已经花了一个早上了解中间件代码。而你对此的评论进一步证明了我需要彻底理解这一点。我会提出另一个问题,一旦我准备好了,希望你会遇到它:)。非常感谢100万人的持续反馈,它非常有帮助!最佳, – Kayote