Hoy hubo bastante revuelo sobre la nueva propuesta para un operador de asignación segura (?=) en JavaScript. Me encanta cómo JavaScript ha mejorado con el tiempo, pero este también es un problema con el que me he encontrado en algunos casos últimamente. Debería preparar un ejemplo rápido de implementación como función, ¿verdad?
Por si no has leído la propuesta, esto es lo que propone:
const [error, value] ?= maybeThrows();
El nuevo operador ?= sería equivalente a llamar al lado derecho de la asignación en un bloque try/catch, devolviendo una matriz. El primer valor de la matriz devuelta sería un error si se arroja algo dentro de la asignación, y el segundo valor sería el resultado de la asignación si no se arroja nada.
Con frecuencia me encuentro con código que se siente bastante feo en torno a tareas y bloques de prueba/captura. Cosas como esta:
let errorMsg; try { maybeThrow(); } catch (e) { errorMsg = "An error message"; }
Para acceder a errorMsg fuera del bloque try/catch usando const o let, debes definirlo fuera del bloque.
El caso más sencillo aquí es el manejo de funciones no asíncronas. Pude prepararme
algunos casos de prueba y una función llamada tryCatch en poco tiempo:
function tryCatch(fn, ...args) { try { return [undefined, fn.apply(null, args)] } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws));
tryCatch llama a la función con los argumentos dados incluidos en un bloque try/catch. Devuelve apropiadamente [indefinido, resultado] si no se produce nada dentro de la función, y [error, indefinido] si se produce algo.
Ten en cuenta que también puedes usar una función anónima con tryCatch si aún no tienes una función lista para llamar.
console.log(tryCatch(() => { throw new Error("It threw"); }));
Las funciones asíncronas se vuelven un poco más complicadas. Una idea que tuve inicialmente fue escribir
una versión completamente asíncrona, tal vez llamada asyncTryCatch, pero ¿dónde está el desafío? ¡Esta es una exploración completamente inútil! Aquí hay una implementación de tryCatch que funciona con funciones asíncronas y no asíncronas:
function tryCatch(fn, ...args) { try { const result = fn.apply(null, args); if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); } return [undefined, result]; } catch (e) { return [e, undefined]; } } function throws() { throw new Error("It threw"); } async function asyncSum(first, second) { return first second; } async function asyncThrows() { throw new Error("It throws async"); } // returns a sum // prints [ undefined, 2 ] console.log(tryCatch(Math.sqrt, 4)); // returns an error // prints [ Error: 'It threw', undefined ] console.log(tryCatch(throws)); // returns a promise resolving to value // prints [ undefined, 3 ] console.log(await tryCatch(asyncSum, 1, 2)); // returns a promise resolving to error // prints [ Error: 'It throws async', undefined ] console.log(await tryCatch(asyncThrows));
Se parece mucho a la versión original, pero con algo de código basado en Promise
incluido por si acaso. Con esta implementación, puede llamar a tryCatch cuando llame a una función no asíncrona y luego llamar a await tryCatch cuando llame a una función asíncrona.
Veamos la parte de la Promesa:
if (result.then) { return new Promise(resolve => { result .then(v => resolve([undefined, v])) .catch(e => resolve([e, undefined])) }); }
if (resultado.entonces) comprueba si la función dada (llamada con aplicar) devolvió una Promesa. Si es así, debemos devolver una Promesa nosotros mismos.
Llamar a result.then(v => resolve([undefinido, v])) hace que la promesa se resuelva en el valor que devolvió la función dada, si no se arroja nada.
.catch(e => resolve([e, undefinido])) es un poco más complicado. Yo escribí originalmente
como .catch(e => rechazar([e, undefinido])), pero eso causa un error no detectado
salirse de tryCatch. Necesitamos resolver aquí porque estamos devolviendo un
matriz, sin arrojar un error.
Con bastante frecuencia tengo casos en los que necesito intentar/atrapar pero me siento como el
El bloque try/catch explícito ocupa mucho espacio y es molesto para las tareas de alcance. No estoy seguro de si lo usaré o no, pero fue una pequeña exploración divertida.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3