2017-04-26 64 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