Gestión de tareas de larga duración en una aplicación React con trabajadores web

 

 

 

  • Patrones de diseño para interfaces de IA, con Vitaly Friedman
  • ¡Registro!

  • Índice
    1. ¿Qué es un trabajador web?
    2. Calcular el enésimo número de Fibonacci
    3. Un ejemplo de trabajador web en acción
    4. Trabajar con varios trabajadores web
    5. Trabajadores web en reacción

    En este tutorial, aprenderemos cómo usar la API de Web Worker para administrar tareas que consumen mucho tiempo y que bloquean la interfaz de usuario en una aplicación de JavaScript mediante la creación de una aplicación web de muestra que aprovecha Web Workers. Finalmente, finalizaremos el artículo transfiriendo todo a una aplicación React.

     

    El tiempo de respuesta es un gran problema cuando se trata de aplicaciones web. Los usuarios exigen respuestas instantáneas, sin importar lo que esté haciendo su aplicación. Ya sea que solo muestre el nombre de una persona o haga cálculos numéricos, los usuarios de aplicaciones web exigen que su aplicación responda a sus órdenes en todo momento. A veces eso puede ser difícil de lograr dada la naturaleza de un solo subproceso de JavaScript. Pero en este artículo, aprenderemos cómo podemos aprovechar la API Web Worker para ofrecer una mejor experiencia.

    Al escribir este artículo, hice las siguientes suposiciones:

    1. Para poder seguirlo, debe tener al menos cierta familiaridad con JavaScript y la API de documentos ;
    2. También debe tener conocimientos prácticos de React para poder iniciar con éxito un nuevo proyecto de React utilizando la aplicación Create React .

    Si necesita más información sobre este tema, he incluido varios enlaces en la sección “ Recursos adicionales ” para ayudarle a ponerse al día.

    Primero, comencemos con Web Workers.

    ¿Qué es un trabajador web?

    Para comprender los Web Workers y el problema que deben resolver, es necesario comprender cómo se ejecuta el código JavaScript en tiempo de ejecución. Durante el tiempo de ejecución, el código JavaScript se ejecuta secuencialmente y paso a paso. Una vez que finaliza un fragmento de código, el siguiente en la línea comienza a ejecutarse, y así sucesivamente. En términos técnicos, decimos que JavaScript tiene un solo subproceso. Este comportamiento implica que una vez que una parte del código comienza a ejecutarse, cada código que viene después debe esperar a que ese código finalice la ejecución. Por lo tanto, cada línea de código "bloquea" la ejecución de todo lo que viene después. Por lo tanto, es deseable que cada fragmento de código finalice lo más rápido posible. Si algún fragmento de código tarda demasiado en finalizar, parecerá que nuestro programa ha dejado de funcionar. En el navegador, esto se manifiesta como una página congelada que no responde. En algunos casos extremos, la pestaña se congelará por completo.

     

    Imagínese conducir por un solo carril. Si alguno de los conductores que van delante de usted deja de moverse por algún motivo, entonces tiene un atasco. Con un programa como Java, el tráfico podría continuar por otros carriles. Por tanto, se dice que Java es multiproceso. Web Workers son un intento de llevar el comportamiento de subprocesos múltiples a JavaScript.

    La siguiente captura de pantalla muestra que la API Web Worker es compatible con muchos navegadores, por lo que debe sentirse seguro al usarla.

    Compatibilidad con el navegador Web Workers. ( Vista previa grande )

    Los Web Workers se ejecutan en subprocesos en segundo plano sin interferir con la interfaz de usuario y se comunican con el código que los creó mediante controladores de eventos.

    Una excelente definición de Web Worker proviene de MDN :

    “Un trabajador es un objeto creado usando un constructor (por ejemplo, Worker()que ejecuta un archivo JavaScript con nombre; este archivo contiene el código que se ejecutará en el hilo del trabajo; los trabajadores se ejecutan en otro contexto global que es diferente del actual window. Por lo tanto, usando el windowacceso directo para obtener el alcance global actual (en lugar de selfdentro de a, Workerdevolverá un error ".

    Un trabajador se crea utilizando el Workerconstructor.

    const worker = new Worker('worker-file.js')

    Es posible ejecutar la mayor parte del código dentro de un trabajador web, con algunas excepciones. Por ejemplo, no puedes manipular el DOM desde dentro de un trabajador. No hay acceso a la documentAPI.

    Los trabajadores y el hilo que los genera se envían mensajes entre sí utilizando este postMessage()método. De manera similar, responden a mensajes utilizando el onmessagecontrolador de eventos. Es importante conseguir esta diferencia. El envío de mensajes se logra mediante un método; recibir un mensaje de respuesta requiere un controlador de eventos. El mensaje que se recibe está contenido en el dataatributo del evento. Veremos un ejemplo de esto en la siguiente sección. Pero permítanme mencionar rápidamente que el tipo de trabajador del que hemos estado hablando se llama "trabajador dedicado". Esto significa que solo se puede acceder al trabajador mediante el script que lo llamó. También es posible tener un trabajador al que se pueda acceder desde múltiples scripts. Estos se denominan trabajadores compartidos y se crean utilizando el SharedWorkerconstructor, como se muestra a continuación.

    const sWorker = new SharedWorker('shared-worker-file.js')

    Para obtener más información sobre los trabajadores, consulte este artículo de MDN . El objetivo de este artículo es ayudarle a empezar a utilizar trabajadores web. Vayamos a ello calculando el enésimo número de Fibonacci.

    Calcular el enésimo número de Fibonacci

    Nota: Para esta y las dos secciones siguientes, estoy usando Live Server en VSCode para ejecutar la aplicación. Ciertamente puedes usar algo más.

    Esta es la sección que estabas esperando. Finalmente escribiremos algo de código para ver a los Web Workers en acción. Bueno, no tan rápido. No apreciaríamos el trabajo que hace un trabajador web a menos que nos encontremos con el tipo de problemas que resuelve. En esta sección, veremos un problema de ejemplo y, en la siguiente sección, veremos cómo un trabajador web nos ayuda a mejorar.

    Imagine que está creando una aplicación web que permite a los usuarios calcular el enésimo número de Fibonacci. En caso de que sea nuevo en el término 'número de Fibonacci', puede leer más sobre él aquí , pero en resumen, los números de Fibonacci son una secuencia de números tal que cada número es la suma de los dos números anteriores.

    Matemáticamente se expresa como:

    Así, los primeros números de la secuencia son:

    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ...

    En algunas fuentes, la secuencia comienza en , en cuyo caso la siguiente fórmula es válida para :F0 = 0n 1

    En este artículo comenzaremos con F 1 = 1. Una cosa que podemos ver inmediatamente a partir de la fórmula es que los números siguen un patrón recursivo. La tarea que nos ocupa ahora es escribir una función recursiva para calcular el enésimo número de Fibonacci (FN).

    Después de algunos intentos, creo que podrás encontrar fácilmente la siguiente función.

    const fib = n = { if (n 2) { return n // or 1 } else { return fib(n - 1) + fib(n - 2) }}

    La función es sencilla. Si n es menor que 2, devuelve n (o 1); de lo contrario, devuelve la suma de n-1y n-2FN. Con funciones de flecha y operador ternario , podemos crear una sola línea.

    const fib = n = (n 2 ? n : fib(n-1) + fib(n-2))

    Esta función tiene una complejidad temporal de . Esto simplemente significa que a medida que aumenta el valor de n, el tiempo necesario para calcular la suma aumenta exponencialmente. Esto lo convierte en una tarea de muy larga duración que potencialmente podría interferir con nuestra interfaz de usuario, para valores grandes de n. Veamos esto en acción.0(2n)

    Nota : Esta no es de ninguna manera la mejor manera de resolver este problema en particular. Mi elección de utilizar este método es para los fines de este artículo.

    Para comenzar, cree una nueva carpeta y asígnele el nombre que desee. Ahora dentro de esa carpeta crea una src/carpeta. Además, cree un index.htmlarchivo en la carpeta raíz. Dentro de la src/carpeta, cree un archivo llamado index.js.

     

    Abra index.htmly agregue el siguiente código HTML.

    !DOCTYPE htmlhtmlhead link rel="stylesheet" href="styles.css"/headbody div h1Computing the nth Fibonnaci number/h1 /div div p id='error'/p div input id='number-input' type='number' placeholder="Enter a number" / button id='submit-btn'Calculate/button /div div id='results-container'/div /div script src="/src/index.js"/script/body/html

    Esta parte es muy sencilla. Primero, tenemos un título. Luego tenemos un contenedor con una entrada y un botón. Un usuario ingresaría un número y luego haría clic en "Calcular". También disponemos de un contenedor para guardar el resultado del cálculo. Por último, incluimos el src/index.jsarchivo en una scriptetiqueta.

    Puede eliminar el enlace de la hoja de estilo. Pero si tienes poco tiempo, he definido algunos CSS que puedes usar. Simplemente cree el styles.cssarchivo en la carpeta raíz y agregue los estilos a continuación:

    body { margin: 0; padding: 0; box-sizing: border-box; } .body-container, .heading-container { padding: 0 20px; } .heading-container { padding: 20px; color: white; background: #7a84dd; } .heading-container h1 { margin: 0; } .body-container { width: 50% } .input-div { margin-top: 15px; margin-bottom: 15px; display: flex; align-items: center; } .results { width: 50vw; } .resultsp { font-size: 24px; } .result-div { padding: 5px 10px; border-radius: 5px; margin: 10px 0; background-color: #e09bb7; } .result-div p { margin: 5px; } span.bold { font-weight: bold; } input { font-size: 25px; } p.error { color: red; } .number-input { padding: 7.5px 10px; } .btn-submit { padding: 10px; border-radius: 5px; border: none; background: #07f; font-size: 24px; color: white; cursor: pointer; margin: 0 10px; }

    Ahora ábrete, src/index.jsdesarrollémoslo lentamente. Agregue el código a continuación.

    const fib = (n) = (n 2 ? n : fib(n - 1) + fib(n - 2));const ordinal_suffix = (num) = { // 1st, 2nd, 3rd, 4th, etc. const j = num % 10; const k = num % 100; switch (true) { case j === 1 k !== 11: return num + "st"; case j === 2 k !== 12: return num + "nd"; case j === 3 k !== 13: return num + "rd"; default: return num + "th"; }};const textCont = (n, fibNum, time) = { const nth = ordinal_suffix(n); return ` p id='timer'Time: span class='bold'${time} ms/span/p pspan id='nth'${nth}/span fibonnaci number: span id='sum'${fibNum}/span/p `;};

    Aquí tenemos tres funciones. La primera es la función que vimos anteriormente para calcular el enésimo FN. La segunda función es simplemente una función de utilidad para adjuntar un sufijo apropiado a un número entero. La tercera función toma algunos argumentos y genera un marcado que luego insertaremos en el DOM. El primer argumento es el número cuyo FN se está calculando. El segundo argumento es el FN calculado. El último argumento es el tiempo que lleva realizar el cálculo.

    Aún en src/index.js, agregue el siguiente código justo debajo del anterior.

    const errPar = document.getElementById("error");const btn = document.getElementById("submit-btn");const input = document.getElementById("number-input");const resultsContainer = document.getElementById("results-container");btn.addEventListener("click", (e) = { errPar.textContent = ''; const num = window.Number(input.value); if (num 2) { errPar.textContent = "Please enter a number greater than 2"; return; } const startTime = new Date().getTime(); const sum = fib(num); const time = new Date().getTime() - startTime; const resultDiv = document.createElement("div"); resultDiv.innerHTML = textCont(num, sum, time); resultDiv.className = "result-div"; resultsContainer.appendChild(resultDiv);});

    Primero, usamos la documentAPI para obtener DOMnodos en nuestro archivo HTML. Obtenemos una referencia al párrafo donde mostraremos mensajes de error; la entrada; el botón calcular y el contenedor donde mostraremos nuestros resultados.

     

    A continuación, adjuntamos un controlador de eventos de "clic" al botón. Cuando se hace clic en el botón, tomamos lo que esté dentro del elemento de entrada y lo convertimos en un número; si obtenemos un valor menor a 2, mostramos un mensaje de error y regresamos. Si obtenemos un número mayor que 2, continuamos. Primero, registramos la hora actual. Después de eso, calculamos el FN. Cuando eso termina, obtenemos una diferencia de tiempo que representa cuánto tiempo tomó el cálculo. En la parte restante del código, creamos un nuevo archivo div. Luego configuramos su HTML interno para que sea la salida de la textCont()función que definimos anteriormente. Finalmente, le agregamos una clase (para darle estilo) y la agregamos al contenedor de resultados. El efecto de esto es que cada cálculo aparecerá por separado divdebajo del anterior.

    Algunos números de Fibonacci. ( Vista previa grande )

    Podemos ver que a medida que aumenta el número, el tiempo de cálculo también aumenta (exponencialmente). Por ejemplo, de 30 a 35, el tiempo de cálculo saltó de 13 ms a 130 ms. Todavía podemos considerar que esas operaciones son "rápidas". A los 40 vemos un tiempo de cálculo de más de 1 segundo. En mi máquina, aquí es donde empiezo a notar que la página deja de responder. En este punto, ya no puedo interactuar con la página mientras se realiza el cálculo. No puedo concentrarme en la entrada ni hacer nada más. radios en vivo y radios live en español

    ¿Recuerda cuando hablamos de que JavaScript era de un solo subproceso? Bueno, ese hilo ha sido "bloqueado" por este cálculo de larga duración, por lo que todo lo demás debe "esperar" a que termine. Puede comenzar con un valor mayor o menor en su máquina, pero seguramente llegará a ese punto. Tenga en cuenta que se necesitaron casi 10 segundos para calcular el valor de 44. Si había otras cosas que hacer en su aplicación web, bueno, el usuario tiene que esperar a que termine Fib(44) antes de poder continuar. Pero si implementó un trabajador web para manejar ese cálculo, sus usuarios podrían continuar con otra cosa mientras se ejecuta.

    Veamos ahora cómo los trabajadores web nos ayudan a superar este problema.

    Un ejemplo de trabajador web en acción

    En esta sección, delegaremos el trabajo de calcular el enésimo FN a un trabajador web. Esto ayudará a liberar el hilo principal y a mantener nuestra interfaz de usuario receptiva mientras se realiza el cálculo.

     

    Comenzar a utilizar trabajadores web es sorprendentemente sencillo. Veamos cómo. Crea un nuevo archivo src/fib-worker.js. e ingresa el siguiente código.

    const fib = (n) = (n 2 ? n : fib(n - 1) + fib(n - 2));onmessage = (e) = { const { num } = e.data; const startTime = new Date().getTime(); const fibNum = fib(num); postMessage({ fibNum, time: new Date().getTime() - startTime, });};

    Observe que hemos movido la función que calcula el enésimo número de Fibonacci, fibdentro de este archivo. Este archivo será ejecutado por nuestro trabajador web.

    Recuerde en la sección Qué es un trabajador web , mencionamos que los trabajadores web y sus padres se comunican mediante el método onmessagey el controlador de eventos postMessage(). Aquí estamos usando el onmessagecontrolador de eventos para escuchar mensajes del script principal. Una vez que recibimos un mensaje, desestructuramos el número del atributo de datos del evento. A continuación, obtenemos la hora actual e iniciamos el cálculo. Una vez que el resultado esté listo, usamos el postMessage()método para publicar los resultados en el script principal.

    Abre, src/index.jshagamos algunos cambios.

    ...const worker = new window.Worker("src/fib-worker.js");btn.addEventListener("click", (e) = { errPar.textContent = ""; const num = window.Number(input.value); if (num 2) { errPar.textContent = "Please enter a number greater than 2"; return; } worker.postMessage({ num }); worker.onerror = (err) = err; worker.onmessage = (e) = { const { time, fibNum } = e.data; const resultDiv = document.createElement("div"); resultDiv.innerHTML = textCont(num, fibNum, time); resultDiv.className = "result-div"; resultsContainer.appendChild(resultDiv); };});

    Lo primero que debe hacer es crear el trabajador web utilizando el Workerconstructor. Luego, dentro del detector de eventos de nuestro botón, enviamos un número al trabajador usando worker.postMessage({ num }). Después de eso, configuramos una función para detectar errores en el trabajador. Aquí simplemente devolvemos el error. Ciertamente puedes hacer más si quieres, como mostrarlo en DOM. A continuación, escuchamos los mensajes del trabajador. Una vez que recibimos un mensaje, desestructuramos timey fibNumcontinuamos el proceso de mostrarlos en el DOM.

    Tenga en cuenta que dentro del trabajador web, el onmessageevento está disponible en el alcance del trabajador, por lo que podríamos haberlo escrito como self.onmessagey self.postMessage(). Pero en el script principal, tenemos que adjuntarlos al propio trabajador.

    En la captura de pantalla siguiente, verá el archivo del trabajador web en la pestaña de fuentes de Chrome Dev Tools. Lo que debe notar es que la interfaz de usuario sigue respondiendo sin importar el número que ingrese. Este comportamiento es la magia de los trabajadores web.

    Un archivo de trabajo web en ejecución. ( Vista previa grande )

    Hemos progresado mucho con nuestra aplicación web. Pero hay algo más que podemos hacer para mejorarlo. Nuestra implementación actual utiliza un solo trabajador para manejar cada cálculo. Si llega un mensaje nuevo mientras uno se está ejecutando, el anterior se reemplaza. Para solucionar esto, podemos crear un nuevo trabajador para cada llamada para calcular el FN. Veamos cómo hacerlo en la siguiente sección.

     

    Trabajar con varios trabajadores web

    Actualmente, manejamos cada solicitud con un solo trabajador. De esta manera, una solicitud entrante reemplazará a una anterior que aún no ha finalizado. Lo que queremos ahora es hacer un pequeño cambio para generar un nuevo trabajador web para cada solicitud. Mataremos a este trabajador una vez que haya terminado.

    Abra src/index.jsy mueva la línea que crea el trabajador web dentro del controlador de eventos de clic del botón. Ahora el controlador de eventos debería verse como se muestra a continuación.

    btn.addEventListener("click", (e) = { errPar.textContent = ""; const num = window.Number(input.value); if (num 2) { errPar.textContent = "Please enter a number greater than 2"; return; } const worker = new window.Worker("src/fib-worker.js"); // this line has moved inside the event handler worker.postMessage({ num }); worker.onerror = (err) = err; worker.onmessage = (e) = { const { time, fibNum } = e.data; const resultDiv = document.createElement("div"); resultDiv.innerHTML = textCont(num, fibNum, time); resultDiv.className = "result-div"; resultsContainer.appendChild(resultDiv); worker.terminate() // this line terminates the worker };});

    Hicimos dos cambios.

    1. Movimos esta línea const worker = new window.Worker("src/fib-worker.js")dentro del controlador de eventos de clic del botón.
    2. Agregamos esta línea worker.terminate()para descartar al trabajador una vez que hayamos terminado con él.

    Entonces, por cada clic en el botón, creamos un nuevo trabajador para manejar el cálculo. Por lo tanto, podemos seguir cambiando la entrada y cada resultado aparecerá en la pantalla una vez que finalice el cálculo. En la captura de pantalla siguiente puedes ver que los valores de 20 y 30 aparecen antes que los de 45. Pero comencé con 45 primero. Una vez que la función regresa para 20 y 30, se publicaron sus resultados y se despidió al trabajador. Cuando todo termine, no deberíamos tener ningún trabajador en la pestaña de fuentes.

    Ilustración de varios trabajadores independientes. ( Vista previa grande )

    Podríamos terminar este artículo aquí, pero si fuera una aplicación de reacción, ¿cómo incorporaríamos a los trabajadores web? Ese es el enfoque de la siguiente sección.

    Trabajadores web en reacción

    Para comenzar, cree una nueva aplicación de reacción usando CRA. Copie el fib-worker.jsarchivo en la public/carpeta de su aplicación de reacción. Poner el archivo aquí se debe al hecho de que las aplicaciones React son aplicaciones de una sola página. Eso es lo único específico del uso del trabajador en una aplicación de reacción. Todo lo que sigue de aquí es puro React.

    En src/la carpeta, cree un archivo helpers.jsy exporte la ordinal_suffix()función desde él.

    // src/helpers.jsexport const ordinal_suffix = (num) = { // 1st, 2nd, 3rd, 4th, etc. const j = num % 10; const k = num % 100; switch (true) { case j === 1 k !== 11: return num + "st"; case j === 2 k !== 12: return num + "nd"; case j === 3 k !== 13: return num + "rd"; default: return num + "th"; }};

    Nuestra aplicación requerirá que mantengamos algún estado, así que cree otro archivo src/reducer.jsy péguelo en el reductor de estado.

     

    // src/reducers.jsexport const reducer = (state = {}, action) = { switch (action.type) { case "SET_ERROR": return { ...state, err: action.err }; case "SET_NUMBER": return { ...state, num: action.num }; case "SET_FIBO": return { ...state, computedFibs: [ ...state.computedFibs, { id: action.id, nth: action.nth, loading: action.loading }, ], }; case "UPDATE_FIBO": { const curr = state.computedFibs.filter((c) = c.id === action.id)[0]; const idx = state.computedFibs.indexOf(curr); curr.loading = false; curr.time = action.time; curr.fibNum = action.fibNum; state.computedFibs[idx] = curr; return { ...state }; } default: return state; }};

    Repasemos cada tipo de acción uno tras otro.

    1. SET_ERROR: establece un estado de error cuando se activa.
    2. SET_NUMBER: establece el valor en nuestro cuadro de entrada en estado.
    3. SET_FIBO: agrega una nueva entrada a la matriz de FN calculadas.
    4. UPDATE_FIBO: aquí buscamos una entrada particular y la reemplazamos con un nuevo objeto que tiene el FN calculado y el tiempo necesario para calcularlo.

    Usaremos este reductor en breve. Antes de eso, creemos el componente que mostrará los FN calculados. Cree un nuevo archivo src/Results.jsy péguelo en el siguiente código.

    // src/Results.jsimport React from "react";export const Results = (props) = { const { results } = props; return ( div className="results-container" {results.map((fb) = { const { id, nth, time, fibNum, loading } = fb; return ( div key={id} className="result-div" {loading ? ( p Calculating the{" "} span className="bold" {nth} /span{" "} Fibonacci number... /p ) : ( p Time: span className="bold"{time} ms/span /p p span className="bold" {nth} /span{" "} fibonnaci number:{" "} span className="bold" {fibNum} /span /p / )} /div ); })} /div );};

    Con este cambio, iniciamos el proceso de convertir nuestro archivo index.html anterior a jsx. Este archivo tiene una responsabilidad: tomar una serie de objetos que representen FN calculados y mostrarlos. La única diferencia con lo que teníamos antes es la introducción de un estado de carga . Entonces, ahora, cuando se está ejecutando el cálculo, mostramos el estado de carga para que el usuario sepa que algo está sucediendo.

    Pongamos las piezas finales actualizando el código que contiene src/App.js. El código es bastante largo, así que lo haremos en dos pasos. Agreguemos el primer bloque de código.

     

    import React from "react";import "./App.css";import { ordinal_suffix } from "./helpers";import { reducer } from './reducer'import { Results } from "./Results";function App() { const [info, dispatch] = React.useReducer(reducer, { err: "", num: "", computedFibs: [], }); const runWorker = (num, id) = { dispatch({ type: "SET_ERROR", err: "" }); const worker = new window.Worker('./fib-worker.js') worker.postMessage({ num }); worker.onerror = (err) = err; worker.onmessage = (e) = { const { time, fibNum } = e.data; dispatch({ type: "UPDATE_FIBO", id, time, fibNum, }); worker.terminate(); }; }; return ( div div className="heading-container" h1Computing the nth Fibonnaci number/h1 /div div className="body-container" p className="error" {info.err} /p // ... next block of code goes here ... // Results results={info.computedFibs} / /div /div );}export default App;

    Como siempre, traemos nuestras importaciones. Luego creamos una instancia de una función de estado y de actualización con el gancho useReducer . Luego definimos una función, runWorker()que toma un número y una identificación y comienza a llamar a un trabajador web para calcular el FN para ese número.

    Tenga en cuenta que para crear el trabajador, pasamos una ruta relativa al constructor del trabajador. En tiempo de ejecución, nuestro código React se adjunta al public/index.htmlarchivo, por lo que puede encontrarlo fib-worker.jsen el mismo directorio. Cuando se completa el cálculo (activado por worker.onmessage), la UPDATE_FIBOacción se envía y luego se despide al trabajador. Lo que tenemos ahora no es muy diferente de lo que teníamos antes.

    En el bloque de retorno de este componente, representamos el mismo HTML que teníamos antes. También pasamos la matriz de números calculados al Results /componente para su renderización.

    Agreguemos el bloque final de código dentro de la returndeclaración.

     div className="input-div" input type="number" value={info.num} className="number-input" placeholder="Enter a number" onChange={(e) = dispatch({ type: "SET_NUMBER", num: window.Number(e.target.value), }) } / button className="push_button red-submit" onClick={() = { if (info.num 2) { dispatch({ type: "SET_ERROR", err: "Please enter a number greater than 2", }); return; } const id = info.computedFibs.length; dispatch({ type: "SET_FIBO", id, loading: true, nth: ordinal_suffix(info.num), }); runWorker(info.num, id); }} Calculate /button /div

    Configuramos un onChangecontrolador en la entrada para actualizar la info.numvariable de estado. En el botón, definimos un onClickcontrolador de eventos. Cuando se hace clic en el botón, verificamos si el número es mayor que 2. Observe que antes de llamar runWorker(), primero enviamos una acción para agregar una entrada a la matriz de FN calculadas. Es esta entrada la que se actualizará una vez que el trabajador termine su trabajo. De esta forma, cada entrada mantiene su posición en la lista, a diferencia de lo que teníamos antes.

    Finalm






    Tal vez te puede interesar:

    1. ¿Deberían abrirse los enlaces en ventanas nuevas?
    2. 24 excelentes tutoriales de AJAX
    3. 70 técnicas nuevas y útiles de AJAX y JavaScript
    4. Más de 45 excelentes recursos y repositorios de fragmentos de código

    Gestión de tareas de larga duración en una aplicación React con trabajadores web

    Gestión de tareas de larga duración en una aplicación React con trabajadores web

    Patrones de diseño para interfaces de IA, con Vitaly Friedman ¡Registro! Índice ¿Qué es un trabajador

    programar

    es

    https://aprendeprogramando.es/static/images/programar-gestion-de-tareas-de-larga-duracion-en-una-aplicacion-react-con-trabajadores-web-1066-0.jpg

    2024-05-21

     

    Gestión de tareas de larga duración en una aplicación React con trabajadores web
    Gestión de tareas de larga duración en una aplicación React con trabajadores web

     

     

    Top 20