Tengo una interfaz en un ESP32.
Estoy tratando de que aparezca una variable Connected en una interfaz para indicarle al usuario si está conectado a dicha interfaz o no.
Estoy usando el siguiente método para OBTENER constantemente la configuración del servidor para actualizar la interfaz.
// get json async function get_json(api_path, options = {}) { // const url = api_path; // console.log(ROOT_URL); // console.log(api_path); const { timeout = 8000 } = options; const controller = new AbortController(); const timeoutID = setTimeout(() => controller.abort(), timeout); const response = await fetch(api_path, { ...options, signal: controller.signal, }); clearTimeout(timeoutID); return response.json(); } async function getSettings() { get_json("/api/settings/get", { timeout: 5000, }).then((json_data) => { // do something with the data connected = true; }).catch(function (error) { // request timeout console.log(error); connected = false; console.log(error.name === "AbortError"); }); } Todo funciona muy bien, excepto la parte de catch .
Digamos que el usuario cambia la IP del ESP. El ESP se reinicia y se reconfigura para usar la nueva dirección IP. Pero el usuario permaneció en la misma página porque connected todavía está configurado como true . En la consola obtengo Uncaught (in promise) DOMException: The user aborted a request. para cada solicitud de getSettings() porque no puedo escribir una catch adecuada.
Básicamente, después de cambiar la IP, getSettings() intenta OBTENER desde una dirección incorrecta, por lo que es normal arrojar algún tipo de error que debo detectar y cambiar la variable Connected a falsa y actualizarla en la interfaz para que el usuario pueda ir/mover/navegar a la dirección IP que acaban de ingresar.
Así es como actualizo conectado en la interfaz:
// check if connected to ESP function connectedStatus() { let conn = document.getElementById("connected"); conn.innerHTML = connected ? "Yes" : "No"; } setInterval(connectedStatus, 500);"¿ get_json() no devuelve una PROMESA?" - Todas las funciones asíncronas devuelven una promesa, pero su función getSettings no espera a que get_json se resuelva.
let delay = ms => new Promise(ok => setTimeout(ok, ms)); async function asyncFn() { delay(2000).then(() => { console.log("wait! 2 secs...") }); console.log("thanks for waiting") } asyncFn() Como puede ver, "thanks for waiting" se imprime primero,
Entonces, nuestra suposición es que, getSettings de hecho modificó el estado connected pero no inmediatamente sino más tarde, pero sus getSettings se resuelven inmediatamente, y no esperó el cambio de estado ( connected ).
Por lo tanto, debe esperar cualquier cambio,
let delay = ms => new Promise(ok => setTimeout(ok, ms)); let state; async function asyncFn() { await delay(2000).then(() => { state = true console.log("wait! 2 secs...") }); console.log("thanks for waiting") } asyncFn().then(() => { console.log("state:", state) })