为什么 'stay on page' dialog 暂停异步函数?
Why does 'stay on page' dialog pauses asynchronous function?
所以这真的让我很烦,我不知道这是浏览器相关的故障还是 javascript 就是这样工作的(我希望是这样)。我创建了一个 fiddle。 https://jsbin.com/laluziqede/1/edit?html,js,output
打开控制台,然后单击按钮。当对话框出现时,该功能正常继续(第一个 console.log 没有暂停),但是 setTimeout 函数中的那个被暂停,只有在您单击 'stay on page' 后才会显示。
但是为什么,有人可以解释一下吗?我想在我的应用程序中使用此 属性(在用户单击“停留”后立即执行操作),但我不确定这是否是一个好习惯,是否适用于所有浏览器和设备。
编辑:这是垃圾箱中的代码:
$(window).on('beforeunload', function() {
return 'Check your console please and then click stay';
});
$('#click-me').on('click', function() {
window.location.href='about:blank';
console.log ('dialog won\'t stop me from showing');
var timer=setTimeout(function() {
console.log('this was paused by the dialog');
},0);
});
Javascript 是单线程的(除非您开始使用 WebWorkers 和其他更新的技术)。因此计时器函数安排了一些要完成的事情,但是它会 仅在 其他一切都让出对 javascript 线程的控制时才完成。所以定时器只是在你要求在一段时间后完成一些工作的意义上是异步的,但它并不是真正的异步,因为在某些事情可以完成的同时其他事情也正在完成。
这也适用于 XHR 请求之类的事情,即使 XHR 请求确实是异步调度的,响应也是一次一个地同步处理的。
你的具体例子有点奇怪,因为它不是另一个 javascript 函数阻塞,它是一个浏览器安全功能,它确保你想让之前的 javascript 操作带走你远离当前页面。不过概念是一样的。
该行为取决于浏览器。我在 Firefox、Chrome、IE 和 Edge 中对其进行了测试,其中只有 Chrome 具有您描述的行为。
区别在于beforeunload
事件的触发时间和处理时间。大多数浏览器在您更改位置 属性 时立即触发事件并立即处理它。 Chrome 要么在导航实际即将发生时触发并处理事件,要么将事件放入队列并稍后像常规事件一样处理它。
在 Chrome 中,setTimeout
处理程序中的代码只有在处理 beforeunload
事件之后才会发生,这可能是因为导航是在任何排队的事件之前处理的,或者是因为超时事件在队列中的卸载事件之后。
所以这真的让我很烦,我不知道这是浏览器相关的故障还是 javascript 就是这样工作的(我希望是这样)。我创建了一个 fiddle。 https://jsbin.com/laluziqede/1/edit?html,js,output
打开控制台,然后单击按钮。当对话框出现时,该功能正常继续(第一个 console.log 没有暂停),但是 setTimeout 函数中的那个被暂停,只有在您单击 'stay on page' 后才会显示。
但是为什么,有人可以解释一下吗?我想在我的应用程序中使用此 属性(在用户单击“停留”后立即执行操作),但我不确定这是否是一个好习惯,是否适用于所有浏览器和设备。
编辑:这是垃圾箱中的代码:
$(window).on('beforeunload', function() {
return 'Check your console please and then click stay';
});
$('#click-me').on('click', function() {
window.location.href='about:blank';
console.log ('dialog won\'t stop me from showing');
var timer=setTimeout(function() {
console.log('this was paused by the dialog');
},0);
});
Javascript 是单线程的(除非您开始使用 WebWorkers 和其他更新的技术)。因此计时器函数安排了一些要完成的事情,但是它会 仅在 其他一切都让出对 javascript 线程的控制时才完成。所以定时器只是在你要求在一段时间后完成一些工作的意义上是异步的,但它并不是真正的异步,因为在某些事情可以完成的同时其他事情也正在完成。
这也适用于 XHR 请求之类的事情,即使 XHR 请求确实是异步调度的,响应也是一次一个地同步处理的。
你的具体例子有点奇怪,因为它不是另一个 javascript 函数阻塞,它是一个浏览器安全功能,它确保你想让之前的 javascript 操作带走你远离当前页面。不过概念是一样的。
该行为取决于浏览器。我在 Firefox、Chrome、IE 和 Edge 中对其进行了测试,其中只有 Chrome 具有您描述的行为。
区别在于beforeunload
事件的触发时间和处理时间。大多数浏览器在您更改位置 属性 时立即触发事件并立即处理它。 Chrome 要么在导航实际即将发生时触发并处理事件,要么将事件放入队列并稍后像常规事件一样处理它。
在 Chrome 中,setTimeout
处理程序中的代码只有在处理 beforeunload
事件之后才会发生,这可能是因为导航是在任何排队的事件之前处理的,或者是因为超时事件在队列中的卸载事件之后。