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

async事件监听器中setTimeout与自定义delay函数均不执行如何解决?

问题根本原因

你的猜测完全正确,问题由switchToSearch()函数触发:

  • 执行window.location.href = "./movies"会立即触发当前页面跳转,浏览器会直接销毁当前页面的所有JS执行上下文,所有未执行的异步回调(包括你注册的setTimeout回调、未完成的Promise回调)都会被直接清除,永远不会执行。
  • 额外补充:你自定义的delay函数本身也存在逻辑错误,Promise构造器中没有调用resolve(),所以即使没有页面跳转,await delay(5000)也会永远处于pending状态,不会执行后续代码。
解决方法

根据你的业务场景二选一即可:

场景1:需要在当前页面跳转前执行populateForm

把页面跳转逻辑放到setTimeout内部,等所有逻辑执行完再跳转:

async function addClickListener() {
  const items = document.querySelectorAll(".li");
  items.forEach((item) => {
    item.addEventListener("click", async (evt) => {
      evt.preventDefault();
      sessionStorage.clear();
      const movieData = await createMovieObject(evt.currentTarget);
      sessionStorage.setItem("movieData", JSON.stringify(movieData));
      clearMovieList();
      removeHidden();
      // 把跳转放到setTimeout内部最后执行
      setTimeout(function () {
        console.log("hello");
        populateForm();
        switchToSearch();
      }, 5000);
    });
  });
}

如果要用await delay的写法,先修正delay函数:

// 修正后的delay函数
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))

// 调用逻辑
await delay(5000)
console.log("hello");
populateForm();
switchToSearch();

场景2:populateForm是跳转后./movies页面的逻辑

直接把执行逻辑迁移到新页面的JS代码中即可,同域名下sessionStorage的内容不会因为页面跳转丢失:

// 写在./movies页面对应的JS中
document.addEventListener('DOMContentLoaded', () => {
  // 存在movieData时执行对应逻辑
  if (sessionStorage.getItem('movieData')) {
    populateForm()
    // 可选:执行完成后清除存储,避免重复触发
    // sessionStorage.removeItem('movieData')
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 02:36:05