等待异步函数后不会调用 onload 事件侦听器

onload event listener is not invoked after awaiting on an asynchronous function

我的代码加载了一个 JSON 文件,该文件稍后在名为 serverTest 的函数中使用。

所以我有这个代码:

async function fetchJSON(url) {
    const response = await fetch(url, {
        headers: { accept: "application/json" }
    });
  
    return response.json();
}

const config = await fetchJSON("./config.json");

window.addEventListener("load", function() {
    serverTest(0);
});

const serverList = new Map(Object.entries(config.servers));

function serverTest(index) {
    // code including serverList
}

问题是加载事件处理程序没有运行。

有人可以帮助我吗?

问题是,通过延迟设置事件处理程序直到 JSON 加载,您错过了 load 事件。

在绝大多数用例中(但来自评论,而不是你的),只需完全删除事件处理程序:

async function fetchJSON (url) {
    const response = await fetch(url, {
        headers: { accept: "application/json" }
    });
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return response.json();
}

const config = await fetchJSON("./config.json");
serverTest(0); // <==== Not wrapped in a `load` event handler

const serverList = new Map(Object.entries(config.servers));

function serverTest(index) {
    //Code including serverList
}

如果您确保您的 script 标签使用 type="module"(如果您使用的是 top-level await,则您的标签必须这样做),它不会在页面 HTML 完全加载并且 DOM 已构建之前,不会成为 运行。 (除非你也有 async 属性;details。)

在您的用例中,等待 load 事件确实有意义,因此您必须等到 load fetch 完成:

async function fetchJSON (url) {
    const response = await fetch(url, {
        headers: { accept: "application/json" }
    });
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return response.json();
}

// Hook up the `load` event *before* loading `config.json`,
// get a promise for when it fires
const loadPromise = new Promise(resolve => {
    window.addEventListener("load", resolve);
});
// Load and wait for `config.json`
const config = await fetchJSON("./config.json");
// Wait for the `load` event (waits only ***very*** briefly
// if the event has already fired, otherwise waits for it
// to fire)
await loadPromise();
serverTest(0);

const serverList = new Map(Object.entries(config.servers));

function serverTest(index) {
    //Code including serverList
}

旁注:请注意,我在调用 json 之前添加了对 ok 的检查。 fetch 仅拒绝它对 网络 错误的承诺,而不是 HTTP 错误。这是 fetch API 中的(恕我直言)一把步兵枪,我在我的旧贫血博客 here.

上报道过