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

227
Visualizações
¿Alguna forma de hacer que se rechace una promesa si tiene un error no detectado?

Es fácil olvidarse de usar try/catch en una función asíncrona o no detectar todos los posibles errores cuando se trabaja con promesas. Esto puede causar una "espera" interminable si la Promesa nunca se resuelve ni se rechaza.

¿Hay alguna forma (como a través de un proxy o alterando el constructor de promesas) para hacer que se rechace una función asíncrona u otras promesas si hay un error no detectado? A continuación se muestra un caso generalizado. Estoy buscando alguna forma de superar la "espera" (como en "p" debe rechazarse cuando se produce el error) sin corregir "badPromise".

 async function badPromise() { const p = new Promise((res) => { delayTimer = setTimeout(() => { console.log('running timeout code...'); if (1 > 0) throw new Error('This is NOT caught!'); // prevents the promise from ever resolving, but may log an error message to the console res(); }, 1000); }); return p; } (async () => { try { console.log('start async'); await badPromise(); console.log('Made it to the end'); // never get here } catch (e) { console.error('Caught the problem...', e); // never get here } })();```
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Las promesas ya se rechazan en el caso de un error sincrónico no detectado:

  • en un constructor Promise , para errores síncronos (lanzados)

    Si se arroja un error en el ejecutor, la promesa se rechaza.

  • en las funciones onFulfilled y onRejected , como en then y catch

    Si una función de controlador: [...] arroja un error, la promesa devuelta por then se rechaza con el error arrojado como su valor.

  • en funciones async

    Valor devuelto: una Promise que se resolverá con el valor devuelto por la función asíncrona, o se rechazará con una excepción lanzada o no detectada dentro de la función asíncrona.

Su problema aquí no es que Promise no maneje errores no detectados, es fundamentalmente porque su error es asíncrono : en lo que respecta a Promise, su función de ejecución es una pequeña función exitosa que llama a setTimeout . En el momento en que su controlador setTimeout se ejecuta y falla, lo hace con su propia pila que no está relacionada con el objeto Promise o su función; no existe nada relacionado con badPromise o p dentro de su controlador setTimeout que no sea la referencia res que el controlador incluye a través del cierre. Al igual que en la pregunta " Manejar el error de setTimeout ", las técnicas para detectar errores en los controladores de setTimeout implicaron editar o ajustar el controlador, y según la especificación HTML para temporizadores , paso 9.2, no hay oportunidad de detectar o intercalar un caso de error para la invocación. de la función pasada a setTimeout .

Aparte de editar badPromise , no hay casi nada que puedas hacer.


(La única alternativa que se me ocurre es modificar/sobrescribir tanto el constructor Promise como el método setTimeout en secuencia, envolviendo el método del constructor Promise para guardar los parámetros de resolve / reject y luego envolviendo el método setTimeout global para envolver el controlador setTimeout con el try / catch que invoca el parámetro de reject recién guardado. Debido a la fragilidad de cambiar ambos servicios globales, desaconsejo soluciones como esta).

about 4 years ago · Juan Pablo Isaza Relatório

0

El problema subyacente es que las devoluciones de llamada del temporizador se ejecutan como código de nivel superior y la única forma de detectar errores en ellas es escuchar eventos de error globales. Aquí hay un ejemplo del uso de un controlador global para detectar tales errores, pero tiene problemas que discutiré debajo del código:

 "use strict"; let delayTimer; // declare variable async function badPromise() { const p = new Promise((res) => { let delayTimer = setTimeout(() => { // declare variable!!! console.log('running timeout code...'); if (1 > 0) throw new Error('This is NOT caught!'); // prevents the promise from ever resolving, but may log an error message to the console res(); }, 1000); }); return p; } (async () => { let onerror; let errorArgs = null; let pError = new Promise( (res, rej)=> { onerror = (...args) => rej( args); // error handler rejects pError window.addEventListener("error", onerror); }) .catch( args => errorArgs = args); // Catch handler resolves with error args // race between badPromise and global error await Promise.race( [badPromise(), pError] ); window.removeEventListener("error", onerror); // remove global error handler console.log("Made it here"); if( errorArgs) { console.log(" but a global error occurred, arguments array: ", errorArgs); } })();

Problemas

  • El código se escribió sin importar lo que se pasa a un controlador de errores global agregado mediante addEventListener ; puede obtener diferentes argumentos si usa window.onerror = errorHandler .
  • La carrera de la promesa se puede ganar con cualquier evento de error que aparezca en la window del ejemplo. No es necesario que se haya generado en la llamada badPromise() .
  • Si varias llamadas a badPromise están activas al mismo tiempo, la captura de errores globales no le indicará qué llamada badPromise error.

Por lo tanto badPromise es realmente malo y debe manejarse con guantes de seda. Si realmente no puede arreglarlo, es posible que deba asegurarse de que solo tenga una llamada pendiente y que no esté haciendo nada más que pueda generar un error global al mismo tiempo. No puedo comentar si esto es posible en su caso.

Alternativa

Una alternativa más genérica puede ser iniciar un temporizador antes de llamar a badPromise y usarlo para agotar el tiempo de espera del estado pendiente de la promesa devuelta;

 let timer; let timeAllowed = 5000; let timedOut = false; let timeout = new Promise( res => timer = setTimeout(res, timeAllowed)) .then( timedOut = true); await Promise.race( [badPromise(), timeout]) clearTimer( timer); console.log( "timed out: %s", timedOut);
about 4 years ago · Juan Pablo Isaza Relatório

0

Puede haber una manera de hacer esto, pero en su caso, creo que realmente desea usar la función de reject dentro de su Promesa en lugar de throw . Eso es realmente para lo que es el rechazo.

 async function badPromise() { const p = new Promise((res, reject) => { delayTimer = setTimeout(() => { console.log('running timeout code...'); if (1 > 0) { reject('This is NOT caught!'); return; } res(); }, 1000); }); return p; } (async () => { try { console.log('start async'); await badPromise(); console.log('Made it to the end'); // never gets here } catch (e) { console.error('Caught the problem...', e); // should work now } })();
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