Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 通过Redux为Web工作者使用承诺_Javascript_Redux_React Redux_Web Worker_Redux Thunk - Fatal编程技术网

Javascript 通过Redux为Web工作者使用承诺

Javascript 通过Redux为Web工作者使用承诺,javascript,redux,react-redux,web-worker,redux-thunk,Javascript,Redux,React Redux,Web Worker,Redux Thunk,我的设置是:Webpack、React、Redux(包括Redux-thunk) 我正在努力将web workers集成到我的mouseMoveeventListener中。当用户在绘图应用程序中绘图时,需要找出哪些元素与“组选择”矩形冲突 对web worker的调用将是异步的,因此,在action creator函数中,我试图提出一个承诺,该承诺在解析时调用有效负载创建函数(resolve),如下所示: 动作创建者: export const groupSelectionPayload =

我的设置是:Webpack、React、Redux(包括Redux-thunk)

我正在努力将web workers集成到我的
mouseMove
eventListener中。当用户在绘图应用程序中绘图时,需要找出哪些元素与“组选择”矩形冲突

对web worker的调用将是异步的,因此,在action creator函数中,我试图提出一个承诺,该承诺在解析时调用有效负载创建函数(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进行异步,但是,我得到了错误:
错误:操作必须是普通对象。将自定义中间件用于异步操作。
后跟:
未捕获异常:未定义

我做错了什么?是否有更明智的方法来处理上述场景

编辑: 我需要安装我拥有的中间件

const store = createStore( reducer, composeEnhancer( applyMiddleware( thunk, promiseMiddleware )));

。。。解决了
操作必须是普通对象的问题…
错误。但是,我仍然得到
未捕获异常:未定义的
错误

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

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作为参数。因此,在该方法中,您可以在异步工作完成时、之前或进行中调度其他操作

此外,redux 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*/);

我对工作者代码没有太多的关注,这只是一个想法,使用middle作为工作者的api…

这是一个很好的答案&我需要思考/理解很多。我不需要所有任务都使用WebWorker,因此不考虑将其集成为中间件。此外,我可能需要多个web工作者来完成不同的任务,例如,当用户将新元素添加到包含已填充元素的画布上时,元素之间的冲突(检查元素坐标与几千个元素之间的关系非常繁重)…我想您对中间件的概念理解有点错误。有了它,你就可以订阅某些感兴趣的行为,而其他所有的都可以通过。基本上你可以为每个工人提供一个中间件,然后我当然提供了。实际上,我花了一上午的时间来理解中间件代码。你的评论进一步说明我需要彻底理解这一点。一旦我准备好了,我会提出另一个问题&希望你能遇到:)。非常感谢您的持续反馈,非常有帮助!最好,看看redux thunk中间件。这是最简单的事情,并显示了概念。
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)
  }
}