【问题标题】:fetch().then().catch(); doesn't catch `Uncaught (in promise) DOMException: The user aborted a request.`fetch().then().catch();没有捕捉到“未捕获(承诺)DOMException:用户中止了请求。”
【发布时间】:2021-12-09 12:10:39
【问题描述】:

我在 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);

【问题讨论】:

  • 你的 getSettings 没有从 get_json 返回承诺,试试return get_json(...。如果你不使用await,你也可以去掉async
  • 您的代码对我来说工作正常,调用getSettings() 确实记录了“DOMException: The user aborted a request.”作为error 和“”的值true" 用于比较错误名称;没有未捕获的拒绝。
  • 您说“但用户停留在同一页面上,因为connected 仍设置为true”,但您没有显示代码的部分您使用connected 并重定向用户。
  • return response.json(); 应该是return await response.json();
  • @Bergi 我无法重定向用户,因为我通过重新启动它来更改 ESP 的网络设置。如果我重新启动它,则服务器已关闭,因此我将没有重定向到的路径。 connected 在上面的代码中。我已经用connected 函数更新了这个问题。

标签: javascript async-await promise try-catch


【解决方案1】:

get_json() 不返回承诺吗?” - 所有异步函数都返回承诺,但您的 getSettings 函数不会等待 get_json 解决。 p>

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)
})

【讨论】:

    猜你喜欢
    • 2019-11-03
    • 2019-05-27
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2017-04-03
    相关资源
    最近更新 更多