Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

274
Visualizações
Hacer que una función onClick espere a que finalice la llamada anterior

Estoy trabajando con React, y tengo un problema al sincronizar clics sucesivamente (eventos onClick):

Mi botón activa una función que llama a dos funciones resetViews y chargeViews ( chargeViews toma tiempo), así que cuando hago clic dos veces rápidamente:

  • resetView se ejecuta bien (establece viewsRef.current en nulo)
  • luego se llama a chargeViews , pero como lleva tiempo, no actualizará viewsRef.current inmediatamente después.
  • por lo tanto, se llama a resetView pero viewsRef.current sigue siendo nulo (porque chargeViews aún no lo actualiza), por lo que no hará nada,
  • luego obtengo dos ejecuciones retrasadas de chargeViews
  • así que después de dos clics obtuve 1 ejecución de resetView y dos ejecuciones retrasadas de chargeViews

Lo que quiero es después de hacer clic, bloquear todo (incluso si el usuario hace clic, no hacemos nada) y ejecutar resetView , luego chargeViews y luego desbloquear para recibir otro clic y hacer el mismo trabajo.

 <MyButton onClick={() => { resetViews(); chargeViews(); }}> Click me </MyButton>

La función que lleva tiempo

 const chargeViews = () => { if(!viewsRef.current){ ... reader.setUrl(url).then(()=>{ reader.loadData().then(()=>{ ... viewsRef.current = reader.getData(); })}) }}

La función que se ignora si hago clic tan rápido (funciona bien si hago clic y espero un poco y luego vuelvo a hacer clic), pero si hago clic y vuelvo a hacer clic rápido, se ignora.

 const resetViews = () => { if (viewsRef.current){ ... viewsRef.current = null; }}
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

No estoy totalmente seguro de entender todo el tema... esto sería un comentario si no requiriera un texto tan largo.

De todos modos, en la medida en que necesite deshabilitar el botón una vez que se haya hecho clic, debe tratarlo al comienzo de su controlador onclick:

 $(this.event.target).prop('disabled', true);

y restablecerlo al final:

 $(this.event.target).prop('disabled', false);

En general, lo que hizo fue correcto en términos de llamar a una serie de funciones para que se ejecuten en cadena dentro del controlador. Pero esas 2 funciones parecen tener una invocación de promesa ... en ese caso, esas no se ejecutarán en cadena esperando que termine la primera.

Por lo tanto, debe pasar la segunda invocación como una devolución de llamada a la primera, para tener la oportunidad de llamarla SOLO una vez que la primera haya terminado su trabajo.

Espero que alguien vaya directamente al grano y sugiera cómo hacer que una función asíncrona "espere" para que, haga lo que haga, cuando se invoque, se esperará a que se complete antes de que se evalúe la siguiente declaración. Por lo general, solo es cuestión de agregar una await antes de su firma, pero hay algunas advertencias.

about 4 years ago · Juan Pablo Isaza Relatório

0

Primero, debe convertir sus funciones que utilizan Promise en funciones asíncronas y luego esperarlas cuando las invoque. Esto facilitará el control del orden de ejecución:

 const chargeViews = async () => { if(!viewsRef.current){ ... await reader.setUrl(url); await reader.loadData(); ... viewsRef.current = reader.getData(); } }

Luego, necesita una referencia isExecuting que será verdadera cuando se ejecuten otras invocaciones y falsa cuando ninguna se esté ejecutando actualmente:

 const isExecuting = useRef(false); const handleClick = async () => { if (!isExecuting.current) { // block other clicks from performing actions in parallel isExecuting.current = true; try { resetViews(); await chargeViews(); } finally { // unblock other clicks isExecuting.current = false; } } };

Por último, use la función handleClick recién creada en su JSX:

 <MyButton onClick={handleClick}> Click me </MyButton>
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda