Skip to main content

Bug Tracker

Side navigation

#9867 closed enhancement (wontfix)

Opened July 20, 2011 03:04AM UTC

Closed July 20, 2011 09:33AM UTC

Last modified July 21, 2011 11:52PM UTC

built-in improvements to responsive-ness of Deferred Promises

Reported by: jokeyrhyme Owned by: jokeyrhyme
Priority: undecided Milestone: None
Component: deferred Version: 1.6.2
Keywords: Cc:
Blocked by: Blocking:
Description

It's a well-known technique in JavaScript to break computationally intensive tasks into asynchronous blocks using setTimeout(fn, 0). My understanding is that it prevents the UI thread from being starved of execution time, so the UI is still responsive.

My suggestion is for Deferred.resolveWith (and therefore, Deferred.resolve) to implement this setTimeout(fn, 0) technique somehow. That way we can use Deferreds to manage our asynchronous blocks, and automatically benefit from a silky-smooth user experience. This does mean additional anonymous functions would be created, and I suppose there could be issues with animation timings.

Attachments (0)
Change History (7)

Changed July 20, 2011 06:36AM UTC by ajpiano comment:1

_comment0: Thanks for your time and interest in helping out the jQuery project! Unfortunately, this proposal is unsuitably vague. While it is certainly within the realm of possibility to somehow leverage Deferreds when doing the setTimeout(fn, 0) technique you describe above, the idea that we can "somehow implement it" into Deferreds and that will autmagically translate into a more responsive UI is not something we can use as a basis for a feature. \ \ Is there a real world use case or implementation of this that you can point to, or can you describe in more detail what you imagine the repercussions on the jQuery API would look like? \ \ For what it's worth, I can't see how adding a timeout into Deffered.resolveWith is a particularly wise idea.1311143882429116
owner: → jokeyrhyme
status: newpending

Thanks for your time and interest in helping out the jQuery project! Unfortunately, this proposal is unsuitably vague. While it is certainly within the realm of possibility to somehow leverage Deferreds when doing the setTimeout(fn, 0) technique you describe above, the idea that we can "somehow implement it" into Deferreds and that will autmagically translate into a more responsive UI is not something we can use as a basis for a feature.

Is there a real world use case or implementation of this that you can point to, or can you describe in more detail what you imagine the repercussions on the jQuery API would look like?

For what it's worth, I can't see how adding a timeout into Deffered.resolveWith is a particularly wise idea. You should use Deferreds to manage the asynchronous behaviour of the timeouts, not expect the creation of Deferreds to create the timeouts for you.

Changed July 20, 2011 07:45AM UTC by jokeyrhyme comment:2

_comment0: Sorry about the vagueness. \ \ The application I am working on performs various computationally-intensive tasks, at it also performs fairly intensive DOM manipulations (large insertions, etc). Some of these tasks are asynchronous (like AJAX, or HTML5 File API, Web Workers) and some of these are synchronous (performing XSLT, element searches, math, etc). \ \ I am currently using Deferreds to break these tasks into smaller chunks. I use then when-then mechanism to force serial execution upon otherwise potentially-parallel tasks. \ \ Something I have noticed is that if I don't throw setTimeout(fn, 0)'s in myself, then the UI for the application will lock-up at times. Looking at the source code for jQuery Deferred Promises, it seems resolves/rejects lead directly into then/fail/done/always, with no room given for the UI to catch up in-between. \ \ To me, it seems that Deferreds really seem to be all about keeping JavaScript responsive (besides providing greater control over asynchronous tasks). My suggestion / question is whether it would be feasible to transparently insert the setTimeout(fn, 0) technique into the current sequence of resolve->then, so that UIs are automatically more responsive. \ \ I am targeting mobile WebKit and mobile Gecko so far. In testing, I have noticed that without the setTimeout technique, my application locks up the UI for 30-60 seconds at times. I guess I am trying to be lazy and avoid having to manually insert setTimeouts into my own code, but to have it done transparently by jQuery Deferreds. \ \ I would not expect the jQuery API to visibly change for developers. However, some control over the timeout interval itself (defaulting to 0) might be appropriate via a jQuery constant, similar to the jQuery.fx.interval constant.1311147968034978
_comment1: Sorry about the vagueness. \ \ The application I am working on performs various computationally-intensive tasks, at it also performs fairly intensive DOM manipulations (large insertions, etc). Some of these tasks are asynchronous (like AJAX, or HTML5 File API, Web Workers) and some of these are synchronous (performing XSLT, element searches, math, etc). \ \ I am currently using Deferreds to break these tasks into smaller chunks. I then use the when-then mechanism to force serial execution upon otherwise potentially-parallel tasks. \ \ Something I have noticed is that if I don't throw setTimeout(fn, 0)'s in myself, then the UI for the application will lock-up at times. Looking at the source code for jQuery Deferred Promises, it seems resolves/rejects lead directly into then/fail/done/always, with no room given for the UI to catch up in-between. \ \ To me, it seems that Deferreds really seem to be all about keeping JavaScript responsive (besides providing greater control over asynchronous tasks). My suggestion / question is whether it would be feasible to transparently insert the setTimeout(fn, 0) technique into the current sequence of resolve->then, so that UIs are automatically more responsive. \ \ I am targeting mobile WebKit and mobile Gecko so far. In testing, I have noticed that without the setTimeout technique, my application locks up the UI for 30-60 seconds at times. I guess I am trying to be lazy and avoid having to manually insert setTimeouts into my own code, but to have it done transparently by jQuery Deferreds. \ \ I would not expect the jQuery API to visibly change for developers. However, some control over the timeout interval itself (defaulting to 0) might be appropriate via a jQuery constant, similar to the jQuery.fx.interval constant.1311148002025880
status: pendingnew

Sorry about the vagueness.

The application I am working on performs various computationally-intensive tasks, at it also performs fairly intensive DOM manipulations (large insertions, etc). Some of these tasks are asynchronous (like AJAX, or HTML5 File API, Web Workers) and some of these are synchronous (performing XSLT, element searches, math, etc).

I am currently using Deferreds to break these tasks into smaller chunks. I then use the when-then mechanism to force serial execution upon otherwise potentially-parallel tasks (only where sequence must be preserved).

Something I have noticed is that if I don't throw setTimeout(fn, 0)'s in myself, then the UI for the application will lock-up at times. Looking at the source code for jQuery Deferred Promises, it seems resolves/rejects lead directly into then/fail/done/always, with no room given for the UI to catch up in-between.

To me, it seems that Deferreds really seem to be all about keeping JavaScript responsive (besides providing greater control over asynchronous tasks). My suggestion / question is whether it would be feasible to transparently insert the setTimeout(fn, 0) technique into the current sequence of resolve->then, so that UIs are automatically more responsive.

I am targeting mobile WebKit and mobile Gecko so far. In testing, I have noticed that without the setTimeout technique, my application locks up the UI for 30-60 seconds at times. I guess I am trying to be lazy and avoid having to manually insert setTimeouts into my own code, but to have it done transparently by jQuery Deferreds.

I would not expect the jQuery API to visibly change for developers. However, some control over the timeout interval itself (defaulting to 0) might be appropriate via a jQuery constant, similar to the jQuery.fx.interval constant.

Changed July 20, 2011 08:05AM UTC by jokeyrhyme comment:3

Here's an example of what I'm talking about:

http://jsfiddle.net/fQLum/

The first function is how everyone would be using Deferreds right now.

The second function is how I am currently using Deferreds, to improve my UI responsiveness. It would be terrific if I didn't have to do the setTimeout myself, but if were done automatically inside the Deferred.

I understand perfectly if this suggestion is rejected. I am just throwing it out there in case this idea is something others will find useful. It might be that this technique can be married with Deferreds in someway that does not effect the core Deferred implementation but is still transparent enough to be terrific short-hand.

Changed July 20, 2011 09:25AM UTC by gnarf comment:4

setTimeout( fn, 0 )
is not "immediate". Take a look at this article.

I see why in your use case you would like for the processing to happen inside of its own event loop, but this is a situation where you could easily write your own wrapper for $.Deferred that injects the logic you need to the specific deferreds you want to "enhance".

I think adding any

setTimeout
inbetween resolve and done is unnecessary for >90% of its uses and much better to be solved by your own wrapper, something like this fiddle.

Changed July 20, 2011 09:33AM UTC by ajpiano comment:5

_comment0: {{{ \ I think adding any setTimeout inbetween resolve and done is unnecessary for >90% of its uses and much better to be solved by your own wrapper, something like this fiddle. \ }}} \ +11311154500960994
component: unfileddeferred
resolution: → wontfix
status: newclosed

"I think adding any setTimeout inbetween resolve and done is unnecessary for >90% of its uses and much better to be solved by your own wrapper, something like this fiddle."

+1

Changed July 20, 2011 02:02PM UTC by dmethvin comment:6

This really does seem like a job for web workers and postMessage, although you'll need a shim for older browsers like IE if you need to support them.

I would not expect the jQuery API to visibly change for developers.

Those are the _worst_ kind of changes, when the semantics are altered in a new version but the syntax stays the same. Adding setTimeout changes a synchronous operation to an asynchronous one.

Changed July 21, 2011 11:52PM UTC by jaubourg comment:7

To be honest, I would have loved to be able to implement resolveWith that way, it would have solved all our try/finally and dead-locking in IE problems.

Sadly, since ajax can be ran synchronously, it just wasn't an option :/