El siguiente código es una sentencia if larga y bifurcada. Cuando uso el nodo para ejecutarlo, la salida de la consola no está undefined (este comportamiento también se replica en el fragmento de código a continuación). Entonces, esencialmente, la declaración if completa no se ejecuta y (supongo) la naturaleza síncrona de javascript hace que la función finalice antes de que la declaración if se ejecute en su totalidad. ¿Cómo puedo esperar a que se ejecute la declaración if antes de que finalice la función (tal vez async-await o una promesa)?
El código es el siguiente (es un validador de fechas de bricolaje que garantiza que las fechas tengan el formato DD/MM/AAAA y que la fecha sea la fecha de hoy o en el futuro):
function validDate(input){ let monthLengths = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (input[2] !== "/" || input[5] !== "/"){ return false; } else if (!Number.isInteger(+input[0]) || !Number.isInteger(+input[1]) || !Number.isInteger(+input[3]) || !Number.isInteger(+input[4]) || !Number.isInteger(+input[6]) || !Number.isInteger(+input[7]) || !Number.isInteger(+input[8]) || !Number.isInteger(+input[9])){ return false; } else if (input.length !== 10){ return false; } else if (input.substr(3, 2) === "02"){ // check if leap year if (+input.substr(0, 2) > 29){ return false; } else if (input.substr(0, 2) === "29" && +input.substr(6, 4)%4 != 0){ return false; } } else if (+input.substr(0, 2) > monthLengths[+input.substr(3, 2) - 1]){ return false; } else if (Date.now() - Date.now()%86400000 - 86400000/3 > Date.parse(input.substr(3, 2) + "/" + input.substr(0, 2) + "/" + input.substr(6, 4))){ return false; } else { return true; } } console.log(validDate("02/02/2022")) function validDate(input){ let monthLengths = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (input.substr(3, 2) === "02"){ // check if leap year if (+input.substr(0, 2) > 29){ return false; } else if (input.substr(0, 2) === "29" && +input.substr(6, 4) % 4 != 0){ return false; } } if (input[2] !== "/" || input[5] !== "/"){ return false; } else if (!Number.isInteger(+input[0]) || !Number.isInteger(+input[1]) || !Number.isInteger(+input[3]) || !Number.isInteger(+input[4]) || !Number.isInteger(+input[6]) || !Number.isInteger(+input[7]) || !Number.isInteger(+input[8]) || !Number.isInteger(+input[9])){ return false; } else if (input.length !== 10){ return false; } else if (+input.substr(0, 2) > monthLengths[+input.substr(3, 2) - 1]){ return false; } else if (Date.now() - Date.now()%86400000 - 86400000/3 > Date.parse(input.substr(3, 2) + "/" + input.substr(0, 2) + "/" + input.substr(6, 4))){ return false; } else { return true; } } console.log(validDate("02/02/2022")) Hay un par de cosas que podemos hacer para que este código funcione un poco mejor. No hay necesidad de usar tanto la palabra clave else , si está devolviendo un valor dentro de una function , ya se está asegurando de que todas las líneas de código después de las declaraciones if no se ejecutarán.
Dicho esto, podemos hacer estos cambios:
function validDate(input){ let monthLengths = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (input[2] !== "/" || input[5] !== "/") return false; if (!Number.isInteger(+input[0]) || !Number.isInteger(+input[1]) || !Number.isInteger(+input[3]) || !Number.isInteger(+input[4]) || !Number.isInteger(+input[6]) || !Number.isInteger(+input[7]) || !Number.isInteger(+input[8]) || !Number.isInteger(+input[9])) return false; if (input.length !== 10) return false; if (input.substr(3, 2) === "02") { // check if leap year if (+input.substr(0, 2) > 29) return false; if (input.substr(0, 2) === "29" && +input.substr(6, 4)%4 != 0) return false; } if (+input.substr(0, 2) > monthLengths[+input.substr(3, 2) - 1]) return false; if (Date.now() - Date.now()%86400000 - 86400000/3 > Date.parse(input.substr(3, 2) + "/" + input.substr(0, 2) + "/" + input.substr(6, 4))) return false; return true; } Ahora que el código está un poco más limpio, podemos simplemente agregar una declaración de return true donde la declaración no if se cumple dentro del bloque de código del año bisiesto.
function validDate(input){ let monthLengths = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; if (input[2] !== "/" || input[5] !== "/") return false; if (!Number.isInteger(+input[0]) || !Number.isInteger(+input[1]) || !Number.isInteger(+input[3]) || !Number.isInteger(+input[4]) || !Number.isInteger(+input[6]) || !Number.isInteger(+input[7]) || !Number.isInteger(+input[8]) || !Number.isInteger(+input[9])) return false; if (input.length !== 10) return false; if (input.substr(3, 2) === "02") { // check if leap year if (+input.substr(0, 2) > 29) return false; if (input.substr(0, 2) === "29" && +input.substr(6, 4)%4 != 0) return false; return true; // <----- This line we need to add. } if (+input.substr(0, 2) > monthLengths[+input.substr(3, 2) - 1]) return false; if (Date.now() - Date.now()%86400000 - 86400000/3 > Date.parse(input.substr(3, 2) + "/" + input.substr(0, 2) + "/" + input.substr(6, 4))) return false; return true; } Podemos aprovechar el objeto Date que JS ya ha incorporado. Sugiero esta siguiente función:
const validDate = (input) => { if (input.length !== 10) return false; const [ day, month, year ] = input.split("/"); if(day.length !== 2 || month.length !== 2 || year.length !== 4) return false; if(!day || !month || !year || isNaN(+day)|| isNaN(+month)|| isNaN(+year)) return false; const now = new Date(), inputDate = new Date(+year, +month - 1, +day, 23, 59, 59); return inputDate >= now; } validDate("02/02/2022");Le sugiero que mueva todo a la declaración de cambio. Sería más necesario y no causará los problemas explicados.