你是不是开着控制台进行测试的,刚刚用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
。
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.7k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
5 回答2k 阅读
在控制台输入alert 不要括号 自己写的就能看到代码 原生的只会看到native code