Search code examples
javascriptsettimeoutblockingonbeforeunload

Why does 'stay on page' dialog pauses asynchronous function?


So this is really bugging me, I don't know if it is a browser related glitch or javascript just works that way ( I hope it does). I created a fiddle. https://jsbin.com/laluziqede/1/edit?html,js,output

Open your console, then click the button. When the dialog appears the function continues normally (first console.log isn't paused), however the one inside setTimeout function is paused and will only show after you click 'stay on page'.

But why, could someone explain this? I want to use this property in my application (execute an action right after user clicks stay), but I'm not sure if it's a good practice and is it working on all browsers and devices.

Edit: Here's the code from the bin:

$(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);

});

Solution

  • The behaviour is browser dependent. I tested it in Firefox, Chrome, IE and Edge, and of those only Chrome has the behaviour that you describe.

    The difference lies either in when the beforeunload event is triggered, or when it is handled. Most browsers trigger the event immediately when you change the location property and also handle it immediately. Chrome either triggers and handles the event when the navigation is actually about to happen, or places the event on the queue and handles it later just like regular events.

    In Chrome the code inside the setTimeout handler will not happen until after the beforeunload event is handled, either because the navigation is handled before any queued events, or because the timout event is after the unload event in the queue.