En una implementación de tabla de símbolos tengo este método:
public getAllSymbols(type?: typeof Symbol, localOnly = false): Promise<Set<Symbol>> { const promise = super.getAllSymbols(type ?? Symbol, localOnly); return new Promise(async (resolve, reject) => { try { let result = await promise; if (!localOnly) { this.dependencies.forEach(async (dependency) => { result = new Set([...result, ...await dependency.getAllSymbols(type, localOnly)]); }); } resolve(result); } catch (reason) { reject(reason); } }); }que funciona bien, sin embargo, ESLint informa 2 usos indebidos de promesas:
Promesa devuelta en argumento de función donde se esperaba una devolución nula.
no-misused-promises
¿Qué tiene de malo este código y cómo tendría que escribirlo para deshacerme del error de linter?
Problemas en tu código:
La función de ejecutor no debería ser async , es un antipatrón
Como super.getAllSymbol(...) ya devuelve una promesa, no es necesario envolverlo en un constructor de promesas: es otro antipatrón . Llame al método then() directamente en la promesa devuelta por super.getAllSymbol(...)
El uso async-await await con forEach() no le dará el resultado esperado porque la función de devolución de llamada de forEach() no esperará a que se establezca la promesa esperada; simplemente continuará con la siguiente iteración.
Puede usar Promise.all() junto con el método map() para obtener el resultado esperado.
También puede usar el bucle for-of , pero usar Promise.all() es mejor si no desea que todas las promesas se establezcan de manera secuencial.
Su código podría reescribirse como (tipos eliminados por simplicidad):
public getAllSymbols(type, localOnly = false) { const promise = super.getAllSymbols(type ?? Symbol, localOnly); return promise .then(result => { if (!localOnly) { return Promise.all(this.dependencies.map(dep => ( dep.getAllSymbols(type, localOnly)) ))) .then(resultArr => { return new Set([...result, ...resultArr]); }); } else { return result; } }); } o podría usar la sintaxis async-await :
public async getAllSymbols(type, localOnly = false) { const result = await super.getAllSymbols(type ?? Symbol, localOnly); if (!localOnly) { const resultArr = await Promise.all(this.dependencies.map(dep => ( dep.getAllSymbols(type, localOnly) ))); return new Set([...result, ...resultArr]); } return result; } Eliminé el bloque catch porque, en mi opinión, el código de llamada debería manejar los errores, si los hay.
La función anterior se puede llamar como:
getAllSymbols(...) .then(result => { ... }) .catch(error => { ... }); o puede usar la sintaxis async-await :
try { const result = await getAllSymbols(...); ... } catch (error) { // handle error }