4 个回答

在控制台输入alert 不要括号 自己写的就能看到代码 原生的只会看到native code

你是不是开着控制台进行测试的,刚刚用chrome测试了一下,如果开着控制台并且控制台取得了焦点,alert不会立即阻塞正在运行的线程,得等到焦点从控制台重新回到页面才会发出alert并阻塞线程;但如果在执行alert之后立即修改window.location.href,此时控制台又取得了焦点,则alert不会立即阻塞线程,jvm转而执行下一个语句修改window.location.href,而这将导致之前尚未发出的alert被取消(我猜的)。

结论是,不要开着控制台测试这段代码。

以下是我的测试代码:

setTimeout(() => $.ajax({
    url: '/',
    type: 'GET',
    success: data => {
        console.log('Before rua');
        alert('Rua!');
        console.log('After rua');
        window.location.href += '#';
    },
    error: (...args) => console.log(...args)
}), 1000);

如果你在1秒内没有将焦点切回页面,则alert不会发出,且window.location.href将被立刻修改;若你在1秒内将焦点切回页面,则alert发出,且window.location.href将会在你将alert dismiss掉后被修改。

或者更简单粗暴一点:

setTimeout(() => {
    console.log('Before rua');
    alert('Rua!');
    console.log('After rua');
    window.location.href += '#';
}, 1000);

同上,1秒内切回页面就能看到alert,dismiss后window.location.href才会被修改,反之alert会被取消。

与上述代码之对比:

setTimeout(() => {
    console.log('Before rua');
    alert('Rua!');
    console.log('After rua');
    // window.location.href += '#';
}, 1000);

这里只是发出一个alert,并没有修改window.location.href,在控制台输入上述代码并运行后等待一秒,看到控制台输出了“Before rua”和“After rua”,这时再将焦点切回页面,才会看到一个alert弹出。

综上,我猜测alert其实也可以是异步的——当渲染进程检测到当前页面没有获取到焦点时,比如被用户最小化了,此时若页面中嵌入的js试图发出alert,则渲染进程不会立刻弹出alert,而是将请求放入一个队列中(pending),等待下一次获取焦点时再一一弹出。

补充一下,目前使用chrome测试的结果是只有在焦点被控制台获取时发出alert,并且在alert之后修改了window.location.href(焦点仍在控制台),才会把alert直接取消掉。最小化浏览器的话浏览器会自动跳出来发出alert

你可以自己实现个alert,当点击确定之后在进行跳转操作

alert停止当前操作,确认后还是会执行下面语句

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题