setTimeout blocked by continuous AJAX requests?

后端 未结 2 1063
悲哀的现实
悲哀的现实 2021-01-14 19:30

Im fixing an issue on a web application that uses setTimeout to inform the back end to keep the session alive. This works as expected in all scenarios except for the followi

相关标签:
2条回答
  • 2021-01-14 20:22

    The setTimeout is not triggering while there are back to back sync AJAX posts happening.

    ...

    My question is: Why is the setTimeout not firing at all? Why is it fired at the end of all the AJAX requests and not in between?

    Because they're synchronous requests. This is one of the many reasons not to use synchronous requests; use asynchronous requests instead.

    When an ajax request is synchronous, it's just like a function call: It ties up the main UI thread. So:

    doThisSyncRequest();
    doThatSyncRequest();
    doTheOtherSyncRequest();
    

    At no point in the above does the thread go back to the idle state and look at its queued work, and so the setTimeout callback that's queued can't run.

    The main UI thread works through a task queue:

    1. Idle while the task queue is empty

    2. When something happens (an "event" in the general sense, including a timer expiring, new code being added, etc.), the browser queues a task with associated JavaScript code for the main UI thread to pick up

    3. When the main UI thread picks up a task, it runs the associated code uninterrupted

    4. If other things happen while that code is running, the browser queues tasks for those things and they wait in the queue

    5. When the main UI thread finishes running the code for one task, it picks up the next task from the queue (if any) or goes back to idling

    Since synchronous requests hold up the thread, it stays stuck in #3 while they're running, and anything else queues up.

    When you use asynchronous requests, the JavaScript code that starts them doesn't get held up while they're running; instead, the code flow continues and finishes, and the main UI thread can continue processing subsequent tasks. Eventually the async request's state changes (for instance, it completes), which queues a task to call the ready state change callback.

    I would recommend using asynchronous requests, for multiple reasons, including that synchronous requests make for a poor user experience because the UI locks up during the request. But just for completeness, you do have an alternative: You could move that background ajax call to keep the session alive into a web worker thread instead. Then, since it's running on a different thread, synchronous ajax calls on the main UI thread don't prevent it from running. I'm not recommending this (I recommend using async requests instead), just flagging it up as an option. Web workers are supported in all modern desktop browsers (but not IE9 and earlier), mobile support is improving, and it's easy to feature-detect whether they're supported and fall back to using the main UI thread if not. But really, async requests are the way to go.

    0 讨论(0)
  • 2021-01-14 20:28

    As you mentioned that the Ajax calls are sync this is what might be holding your setTimeout from firing. You can try this by making you Ajax calls async.

    Thanks

    0 讨论(0)
提交回复
热议问题