我在ESP32上有一个接口。
我正试图有一个Connected
变量显示在一个界面信号用户,如果他是连接到所述接口或不。
我使用以下方法不断地从服务器获取配置,以便更新接口。
// 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");
});
}
除了catch
部分,其他都很好。
假设用户修改了ESP的IP地址,ESP重启并重新配置使用新的IP地址。但是用户停留在同一页面上,因为connected
仍然被设置为true
。在控制台中,我为每个请求getSettings()
获得Uncaught (in promise) DOMException: The user aborted a request.
,因为我无法编写适当的catch
。
基本上,在IP更改后,getSettings()
试图从错误的地址获取,所以抛出某种错误是正常的,我应该捕获并将Connected
变量更改为false并在界面中更新它,以便用户可以去/移动/导航到他们刚刚输入的IP地址。
这是我在界面中更新连接的方式:
// check if connected to ESP
function connectedStatus() {
let conn = document.getElementById("connected");
conn.innerHTML = connected ? "Yes" : "No";
}
setInterval(connectedStatus, 500);
"难道get_json()
不返回PROMISE吗?">-所有异步函数都返回PROMISE,但是您的getSettings
函数不等待get_json
成为解析
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()
可以看到"thanks for waiting"
先打印,
所以我们的猜测是,getSettings
确实修改了connected
的状态,但不是立即,而是稍后,但你的getSettings
立即解决,而你没有等待状态(connected
)的变化。
所以你需要等待任何变化,
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)
})