beforeunload
回调函数中可以做什么和不能做什么?
是否可以打开XHR/fetch并向服务器发送数据? 如果不行,是否可以只发送数据,并且没有任何成功回调会阻塞?
是否可以使用window.location
更改页面的位置?
该函数执行多长时间?
window.addEventListener("beforeunload", function (event) {
// code
});
beforeunload
回调函数中可以做什么和不能做什么?
是否可以打开XHR/fetch并向服务器发送数据? 如果不行,是否可以只发送数据,并且没有任何成功回调会阻塞?
是否可以使用window.location
更改页面的位置?
该函数执行多长时间?
window.addEventListener("beforeunload", function (event) {
// code
});
在“beforeunload”回调中,您可以放置任何想要的内容,但是除非使用同步/阻塞代码,否则不能保证它将被执行。
这里是一个用于演示目的的阻塞睡眠函数:
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
任何同步、阻塞的代码都保证会完整地执行:
window.addEventListener("beforeunload", function (event) {
console.log("Blocking for 1 second...");
sleep(1000);
console.log("Done!!");
});
任何异步代码(即带有回调函数的代码)都将在事件循环队列中排队,但根据您的浏览器何时完成“卸载”操作(例如关闭窗口,刷新页面),它可能会或可能不会完成执行。时间取决于计算机的性能。例如,在我的计算机上,具有log语句的10ms超时仍然执行,因为我的浏览器没有时间刷新/关闭页面。
window.addEventListener("beforeunload", function (event) {
setTimeout(() => {
console.log("Timeout finished!"); // Odds are this will finish
}, 10);
console.log("Done!!");
});
然而,100毫秒的超时时间永远不会被执行:
window.addEventListener("beforeunload", function (event) {
setTimeout(() => {
console.log("Timeout finished!");
}, 100);
console.log("Done!!");
});
要保证函数运行完成的唯一方法是确保编写的代码是同步的,并且会阻塞事件循环,就像第一个示例中一样。
while(!asyncCompleted);
阻塞器会起作用吗? - Vic为了帮助第一个回答评论区的一些人,可以查看此功能,在unload事件期间发出XHR请求:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon