2017-04-26 6 views
1

Mein Setup ist: Webpack, React, Redux (inkl. Redux-Thunk).Verwenden Sie Versprechen für Web-Worker mit Redux

Ich arbeite auf die Integration von Web-Arbeiter in meinem EventListener mouseMove. Es muss herausgefunden werden, welche Elemente eine Kollision mit der Gruppenauswahl haben, wenn der Benutzer die Zeichen-App einzeichnet.

Der Aufruf von Web-Arbeiter wird async so sein, in der Action-Schöpfer Funktion, Ich versuche, ein Versprechen zu erhöhen, die auf Vorsatz, die Nutzlast fordert die Schaffung func (resolve) wie folgt:

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", 
    })); 
}; 

ich für async Redux-Thunk verwende, doch, erhalte ich die Fehlermeldung: Error: Actions must be plain objects. Use custom middleware for async actions. Gefolgt von: uncaught exception : undefined

Was mache ich falsch und gibt es einen vernünftigeren Weg, das oben beschriebene Szenario zu behandeln?

Edit: Ich brauchte redux-promise Middleware zu installieren, die ich habe.

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

..., die den Actions must be plain objects ... Fehler behoben ist. Allerdings bekomme ich immer noch den uncaught exception : undefined Fehler.

Antwort

1

Nun, ich denke, die Aktion Schöpfer wie so aussehen sollte:

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 die Methode aufrufen vom Schöpfer mit Versand als Parameter zurückgegeben. Innerhalb dieser Methode können Sie also andere Aktionen ausführen, wenn der asynchrone Vorgang abgeschlossen ist, oder vorher oder beim Fortschritt.

Zusätzlich gibt redux thunk den Wert der vom Aktionsersteller bereitgestellten Funktion zurück. So können auch:

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

}); 

Und in der Komponente, die Sie als:

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

Aber wenn man mit einem WebWorker zu tun haben, denke ich, Middleware zu einem besseren Ort wäre, den Code zu setzen:

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

Ich habe nicht zu viel über die Arbeiter-Code, es ist nur über die Idee, um die Mitte als API für den Arbeiter zu verwenden ...

+0

das ist eine wunderbare Antwort und eine Menge für mich zum Nachdenken. Ich brauche keinen Web-Mitarbeiter für alle Aufgaben und denke daher nicht daran, es als Middleware zu integrieren. Zusätzlich benötige ich möglicherweise mehrere Web-Arbeiter für verschiedene Aufgaben, z. Kollision zwischen Elementen, wenn der Benutzer ein neues Element mit bereits gefüllten Elementen in die Arbeitsfläche einfügt (das Überprüfen der Koordinaten eines Elements gegen einige tausend Elemente ist schwer) ... – Kayote

+1

Ich glaube, Sie haben das Konzept der Middleware etwas missverstanden. Mit ihr abonnierst du bestimmte Aktionen von Interesse, alle anderen passieren sie einfach. Grundsätzlich können Sie für jeden Mitarbeiter eine Middleware bereitstellen. – philipp

+0

Dann habe ich sicherlich getan. Ich habe den ganzen Morgen damit verbracht, den Middleware-Code zu verstehen. Und dieser Kommentar von Ihnen bekräftigt, dass ich das gründlich verstehen muss.Ich werde eine weitere Frage aufwerfen, sobald ich bereit bin, und hoffentlich wirst du darauf stoßen :). Vielen Dank für die kontinuierliche Rückmeldung, es ist sehr hilfreich! Am besten, – Kayote

Verwandte Themen