You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何所有文件加载成功后网站仍显示加载图标?Promise相关问题

问题原因
  • 核心问题出在document.write的调用时机:你在异步的async函数中调用document.write,此时浏览器初始的文档加载流程已经结束,document.write会隐式触发document.open()开启新的文档流,而你没有手动调用document.close()关闭文档流,浏览器会默认认为文档还在加载中,所以加载图标一直不会消失。
  • 次要问题:你把脚本放在head标签内直接执行,没有等待DOM加载完成,虽然你的场景没有触发报错,但属于不规范的写法。
修复方案

方案1:替换document.write为标准DOM操作(更推荐)

修改controller.js的代码,直接向body插入内容,不需要操作文档流,也不会触发加载状态异常:

function myDisplayer(some) {
  document.body.innerHTML = some;
}
async function loadController(){
    let myPromise = new Promise(function(myResolve, myReject) {
      let req = new XMLHttpRequest();
      req.open('GET', "controllerDummy.html");
      req.onload = function() {
        if (req.status == 200) {
          myResolve(req.response);
        } else {
          myReject("File not Found");
        }
      };
      req.send();
    });
    myDisplayer(await myPromise);
}
// 等待DOM加载完成再执行,避免body未初始化报错
document.addEventListener('DOMContentLoaded', loadController)

方案2:保留document.write,手动关闭文档流

如果要保留原来的写法,只需要在document.write后追加关闭文档流的逻辑即可:

function myDisplayer(some) {
  document.write(some);
  document.close(); // 手动关闭文档流,通知浏览器加载完成
}
原有实现是否过时?

是,目前已经有更简洁的标准实现方式:

  • 网络请求可以直接用fetchAPI,原生支持Promise,不需要手动封装XMLHttpRequest,配合async/await语法非常简洁:
async function loadController(){
  try {
    const res = await fetch('controllerDummy.html')
    if(!res.ok) throw new Error('File not Found')
    const content = await res.text()
    document.body.innerHTML = content
  } catch (err) {
    console.error(err)
  }
}
document.addEventListener('DOMContentLoaded', loadController)
  • document.write属于非常早期的DOM操作API,现在已经不推荐使用,尤其是异步场景下很容易触发各种奇怪的问题,优先使用innerHTML或者appendChild等标准DOM操作方法。

内容的提问来源于stack exchange,提问作者MoulikChawla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 03:39:01