Results 1 to 4 of 4

Thread: [RESOLVED] Promises, promises...I'm Unloading

  1. #1

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,943

    Resolved [RESOLVED] Promises, promises...I'm Unloading

    I noticed that people tended to unload my page by mistake a lot. The page is a series of forms that are displayed via JQuery, and the whole thing will be used almost exclusively offline. Because of the multiple forms approach, it looks to the user like they are navigating through pages, when they are actually just staying on one page all the time.

    My first thought about solving the unloading issue was to store the current state into the IndexDB that backs the whole thing (it's almost always offline, so offline storage is the key). This was interesting, but entirely practical. However, there are about four tables that get saved, and this is done the semi-typical IndexDB way using promises. So, in the Unload event, I store everything. This works fine as long as the promises complete before the unload event completes...which ONLY happens in testing. In practice, nothing gets saved because the event method ends and the page unloads before the promises have completed.

    Better yet, I'm using Linq2IndexDB, as a nice library for doing the writing, so I'm not dealing with the promises directly.

    All is fine as long as the async activity gets a chance to run to completion. I can only think of a few alternatives:

    1) A spin wait on a variable set to true in the completion of the last promise (or a counter variable incremented by each completion). This should work, but seems a bit painful.

    2) Using BeforeUnload rather than Unload, since that event appears to be intended to allow the cancelation of the unload. This would work, because the unloads that I have seen are accidental unloads due to people hitting the back button out of habit (they know it is only one page, they do it reflexively). Asking them if they really mean to exit would be reasonable, but intrusive.

    Is there a better approach?
    My usual boring signature: Nothing

  2. #2
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: Promises, promises...I'm Unloading

    I'm afraid I've no idea about promises (I sometimes make them, but only before breaking them) but one alternative to the beforeunload event is to use the History API:
    http://html5doctor.com/history-api/
    https://developer.mozilla.org/en-US/...ers/onpopstate

    This will trap back and forward navigation events. If you wish, you can use it to set the URL for each form that appears on your page (if that is a suitable metaphor for your application ... I don't know).

    To trap the window or tab being closed, you need to use beforeunload. It is intrusive... but potentially better than losing data.

    Another approach would be to save state on a regular interval, or when the user navigates between input elements.

    By the way, it seems to be possible to read/write in a synchronous fashion. I'm not sure if this would work in your case:
    https://developer.mozilla.org/en-US/...bjectStoreSync
    Last edited by penagate; Mar 27th, 2015 at 03:47 PM.

  3. #3
    Frenzied Member tr333's Avatar
    Join Date
    Nov 2004
    Location
    /dev/st0
    Posts
    1,605

    Re: Promises, promises...I'm Unloading

    I've got nothing more to add on penagate's answer, but you might want to read a tutorial on promises. They can make life much easier if you know how to use them properly.
    CSS layout comes in to the 21st century with flexbox!
    Just another Perl hacker,

  4. #4

    Thread Starter
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,943

    Re: Promises, promises...I'm Unloading

    I had forgotten that I started this thread. Thanks for the replies.

    The situation has changed. After writing this, I did look into the asynchronous model being used by JS. It isn't what I thought it was, but one thing that became perfectly clear is that I wasn't going to be able to solve this in this fashion. The unload event is actually deprecated, and will probably be dropped in some future version of JS. Beforeunload is the preferred event, but it IS intrusive, and despite that fact, it isn't sufficient. I was thinking that the asynchronous model was using threads, which it may in some browsers, or at some time in the future, but at this time that is not the case (and can never be counted on, even in the future). There is no way to pause the current operation and let all deferred promises complete before continuing, and any attempt to do so would introduce a MAJOR exception into the JS execution model, so I don't believe that situation will ever change. JS never blocks, as it stands, but blocking is what would be required.

    There are (sort of) ways to get around this in most situations, but not in the situation of the page being unloaded. In that case, continuation is terminal, which means that only blocking would work. The only blocking in JS of any sort is something like the alert, but the JS protocol explicitly states that alert can be ignored in the unload event...which is probably what the beforeunload is all about, but that's a different matter.

    So, I ended up re-writing the logic such that it saves all data entered as it is entered. There is never any unsaved data, so there is nothing to be lost by an unload, browser close, or anything of that nature.
    My usual boring signature: Nothing

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width