New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deferred updates, part 2: default option #1753
Conversation
I like both |
👍 - The new naming makes the intent more clear |
expect(runValues).toEqual([1,2,3]); | ||
}); | ||
|
||
it('Should keep correct state if a task throws an exception', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that runEarly should throw if one of the handlers it runs throws. This means everywhere you use runEarly, you have to put all your code in try/catch, because you have no idea whether some completely unrelated task will throw. And people can use it as a way of detecting whether or not at least one scheduled handler does throw (without telling you which handler), which encourages excessive use of runEarly, undermining the benefit.
Could we change this so runEarly doesn't throw? Throwing doesn't seem to communicate anything useful, as you have no idea what threw (and I don't think we should add a way of reporting what threw, as it would lead to really weird use cases). Then all task exceptions are definitely going to land in the same place - the onError
callback (or window.onerror
if you catch at that level).
@SteveSanderson I'm glad you brought up exception handling since it was something that I felt a bit unsure about. The main advantage of falling out of the task loop on an exception is that the error gets reported right away in the correct context. We already have somewhat of a precedence for this because if you update an observable, it can trigger any number of manual subscriptions, computed observables, and bindings to run, and errors will both cancel the remaining updates and get thrown back to the caller (the code updating the observable). I'm also not too concerned about the remaining tasks being rescheduled after an exception, since if using But, I do agree with your concerns about errors when using
|
…or all observables ko.tasks.runEarly runs all pending tasks immediately ko.tasks.reset ensures tests leave a clean slate
Updates based on comments by @SteveSanderson in #1738
5e88367
to
c702a22
Compare
…e queue get run. Rename ko.tasks.reset to ko.tasks.resetForTesting so that its intent is more clear.
After trying a couple of methods, I decided that the simplest and most clear way is to have all task errors deferred using |
I'm merging this now so we can move on to the next part. |
Deferred updates, part 2: default option
After reading @brianmhunt's comment on #1603, I thought of using the same API for controlling whether to use global deferred updates. But I like
ko.options
instead ofko.settings
, so we haveko.options.deferUpdates
.Following the information I presented in #1728, this also includes a method to run pending tasks immediately. Instead of
ko.tasks.runTasks
, the name I had used in #1738, I decided onko.tasks.runEarly
, which I think makes its purpose more clear.