2017-04-26 32 views
1

我的设置是:的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错误。

回答

1

嗯,我想你的行动的创建者应该像这样:

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 ...

+0

这是一个很好的答案,对我来说很重要。我不需要网络工作者来完成所有任务,因此不会考虑将它作为中间件集成。另外,我可能需要多个网络工作者来完成不同的任务,例如元素之间的碰撞,当用户添加了新的元素已填写元素(检查元素的坐标对几千个元素被重)以帆布... – Kayote

+1

我想你missunderstood中间件的概念了一下。有了它,你就可以订阅某些感兴趣的动作,所有其他人都可以通过。基本上你可以为每个工人提供一个中间件。 – philipp

+0

那我当然做到了。我实际上已经花了一个早上了解中间件代码。而你对此的评论进一步证明了我需要彻底理解这一点。我会提出另一个问题,一旦我准备好了,希望你会遇到它:)。非常感谢100万人的持续反馈,它非常有帮助!最佳, – Kayote