Deferred callback list behavior and 'stopOnFalse'
in Using jQuery
•
9 years ago
I am using deferreds in a public API as the return values for methods that spawn AJAX requests. This has a number of advantages, most notably allowing users of the API to respond to both success and error states of the request in an elegant manner. However I've been facing one major issue with this pattern: there is default behavior that the methods perform for both success and error conditions that can't be overridden by API users. Essentially the problem stems from there being no feedback mechanism built into deferred callback lists. 90% of the time API users will not need to alter basic behavior, but for highly custom implementations that behavior must be overridden an handled independently. This ideally would involve returning false from callbacks registered through done() and fail() to prevent handlers registered after them, and the default actions, from running. This could be achieved simply by adding the new 'stopOnFalse' flag to deferred callback lists (or at least the option to).
I realize that part of the power of deferreds is that callbacks are guaranteed to run no matter when they are registered, but I believe that there are cases where more control is necessary. The 'stopOnFalse' solution is akin to the existing behavior of event handler lists. jQuery users are intimately familiar with returning false from a handler to stop bubbling, and by doing so prevent handlers bound higher up in the DOM tree from running. Admittedly, returning false in a deferred callback would be analogous to event.stopImmediatePropagation() and not just returning false, but because bubbling is not occurring with deferred callback lists, I think this behavior would be intuitive. I have a feeling that there is some other fundamental design decision of deferreds that this violates, but it is not obvious to me.
I've looked into using deffered.pipe() to achieve my indented behavior, but due to the nature of APIs I don't think it's possible. Once the deferred is handed off to API users, they cannot alter how it gets resolved and can no longer communicate with the method they called (i.e. returning false from a passed in callback). An obvious solution to my immediate problem is to provide a boolean parameter in every method that prevents the default behavior from happening, but this would require introducing inconsistency into the method signatures due to their wide variety of accepted parameters. The importance of unchanging and consistent APIs is paramount, and is essentially why I feel this issue is worth discussing at all.
My question can be distilled down to this: what are the negative effects of having the option to apply the 'stopOnFalse' flag to deferred callback lists?
1