What is and what is not possible to do inside the beforeunload
callback ?
Is it possible to open an XHR/fetch and send data to the server ? If no, is i
To help some of the people in the comments on the first answer, check out this functionality to make an XHR request during the unload event: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon
You can put anything you want inside of a "beforeunload" callback, you're just not guaranteed it will execute unless you use synchronous/blocking code.
Here's a blocking sleep function I'll use for demonstration purposes:
function sleep(delay) {
var start = new Date().getTime();
while (new Date().getTime() < start + delay);
}
Any synchronous, blocking code is guaranteed to execute to completion:
window.addEventListener("beforeunload", function (event) {
console.log("Blocking for 1 second...");
sleep(1000);
console.log("Done!!");
});
Any async code (i.e. code with callbacks) like the code below will be queued on the event loop, but it may or may not finish executing depending on when your browser completes the "unload" action (e.g. close window, refresh page.) The time here really depends on your computer's performance. On my computer, for example, a timeout of 10ms with log statement still executes because my browser hasn't had time to refresh/close the page.
window.addEventListener("beforeunload", function (event) {
setTimeout(() => {
console.log("Timeout finished!"); // Odds are this will finish
}, 10);
console.log("Done!!");
});
A timeout of 100ms, however, is never executed:
window.addEventListener("beforeunload", function (event) {
setTimeout(() => {
console.log("Timeout finished!");
}, 100);
console.log("Done!!");
});
The only way to guarantee your function will run to completion is to make sure you're writing synchronous code that blocks the event loop as in the first example.