React multi-thread con useWorker

Mattepuffo's logo
React multi-thread con useWorker

React multi-thread con useWorker

Come sappiamo Javascript è single-thread, ma è possibile eseguire operazioni in background usando i web worker.

Solo che usarli in React può essere un pò complicato, soprattutto a livello di configurazione.

Ma possiamo usare useWorker!

Per installare la libreria:

npm install @koale/useworker

Qui sotto un esempio di codice ripreso dal sito ufficiale:

import React from "react";
import {useWorker, WORKER_STATUS} from "@koale/useworker";

const numbers = [...Array(50000)].map(() =>
    Math.floor(Math.random() * 1000000)
);

const bubleSort = input => {
    let swap;
    let n = input.length - 1;
    const sortedArray = input.slice();
    do {
        swap = false;
        for (let index = 0; index < n; index += 1) {
            if (sortedArray[index] > sortedArray[index + 1]) {
                const tmp = sortedArray[index];
                sortedArray[index] = sortedArray[index + 1];
                sortedArray[index + 1] = tmp;
                swap = true;
            }
        }
        n -= 1;
    } while (swap);

    return sortedArray;
};

function App() {
    const [sortWorker, {
        status: sortWorkerStatus,
        kill: killWorker
    }] = useWorker(bubleSort);

    React.useEffect(() => {
        console.log("WORKER STATUS: ", sortWorkerStatus);
    }, [sortWorkerStatus])

    const onWorkerSortClick = () => {
        sortWorker(numbers).then(result => {
            console.log("RISULTATO: ", result);
        });
    };

    return (
        <div>
            <section className="App-section">
                <button
                    type="button"
                    disabled={sortWorkerStatus === WORKER_STATUS.RUNNING}
                    className="App-button"
                    onClick={() => onWorkerSortClick()}>
                    {sortWorkerStatus === WORKER_STATUS.RUNNING
                        ? `Loading...`
                        : `CLICCA PER AVVIARE IL SORTING`}
                </button>
                {sortWorkerStatus === WORKER_STATUS.RUNNING ? (
                    <button
                        type="button"
                        className="App-button"
                        onClick={() => killWorker()}
                    >
                        KILL WORKER
                    </button>
                ) : null}
            </section>
        </div>
    );
}

export default App;

Ho messo tutto insieme facendo un pò di pulizia, giusto per dimostrare il funzionamento.

Come potete vedere, l'ordinamento avviene in background.

Ovviamente tutto ciò ha anche delle limitazioni:

  • i web worker non hanno accesso al DOM
  • quando un worker è attivo non può essere riattivato fino a quando non è terminato
  • la velocità di esecuzione dei web worker dipende dalla potenza della CPU del pc su cui è stato lanciato

Enjoy!


Condividi

Commentami!