使用Redux的Web-Worker承诺

时间:2017-04-26 12:04:16

标签: javascript redux react-redux web-worker redux-thunk

我的设置是:Webpack,React,Redux(包括redux-thunk)。

我正在努力在我的mouseMove eventListener中集成Web worker。需要找出哪些元素与“组选择”相冲突。用户在绘图应用程序中绘制的矩形。

对web-worker的调用将是异步的,因此,在action-creator函数中,我试图提出一个promise,在解析后,调用有效负载创建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错误。

1 个答案:

答案 0 :(得分:1)

嗯,我想你的动作创作者应该是这样的:

---
title: New Hampshire Statewide Age Adjusted Incedence Rates of Lyme
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
---

```{r setup, include=FALSE, message=FALSE, warning=FALSE, echo=TRUE}

```

Row
-----------------------------------------------------------------------

### 
```{r, aarState, message=FALSE, warning=FALSE}

library(flexdashboard)
library(rbokeh)
#load state-wide age adjusted rates

aar<-read.csv("stateAAR.csv")
figure(title=" Age Adjusted Rates by Year",width= 1500, height =600) %>%
  ly_segments(year, lci*100000, year, uci*100000, data=aar, color = "#b37700", width = 1) %>%
  ly_points(year, adj.rate*100000, glyph = 21, size=6, data = aar, hover= "<strong>Rate per 100,000:</strong> @rateHundThou </br> <strong>Upper Confidence:</strong> @uciHT </br><strong> Lower Confidence:</strong> @lciHT " , color="#666622" )%>%

  x_axis(label ='Year')%>%
  y_axis(label ='Age Adjusted Rate')


```  

Row

Redux thunk将使用dispatch作为参数调用创建者返回的方法。因此,在该方法中,您可以在完成异步内容时,在执行之前或之前调度其他操作。

此外,redux thunk将返回动作创建者提供的函数的值。所以也可以:

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 }}))
}

在你的组件中:

const someAction = id => dispatch => new Promise((res, rej) => {
  const result = something(id);
  if (result !== null) {
    dispatch({type: 'success', payload: { result }})
    res(result);
  } else { … }

});

但是当你处理webWorker时,我认为中间件是放置代码的更好的地方:

this.props.action(<id>).then(/*getting fancy here, update State or something*/);

我没有太在意工人代码,只是想法,使用中间作为工人的api ......