-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Added throttling function #1996
Conversation
Seems that this branch got somehow broken, there's a little too much commits in there 🙂 |
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.
Some things to be resolved. On top of this this code is a copy and pasta from CKEDITOR.tools.eventBuffer
we should refactor both methods to use a common code base.
tests/core/tools.js
Outdated
foo = 'foo', | ||
buz = 'buz', | ||
message, | ||
buffer = CKEDITOR.tools.throttle( 200, function( arg ) { |
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.
Once again, use sinon.stub / spy for function mocking, it will make the API much, much clearer. 🙂
If you'd use sinon, you had assertion like that:
sinon.assert.calledOnce( inputSpy );
sinon.assert.calledWithExactly( inputSpy, 'foo' );
And then:
assert.areSame( 2, inputSpy.callCount );
sinon.assert.calledWithExactly( foo.getCall( 1 ), 'buz' )
Just to make few examples. It's a really convenient API.
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.
The problem with sinon.assert
is that it doesn't allow for meaningful assert messages. because of that issue, I will use assert.isTrue( inputSpy.calledOnce, msg )
assert.
tests/core/tools.js
Outdated
buffer.input(); | ||
buffer.reset(); | ||
|
||
wait( 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 believe you could even call it synchronously after reset and check the counter.
core/tools.js
Outdated
* Throttles `input` events (or any `input` calls) | ||
* and triggers `output` not more often than once per `minInterval`. | ||
* | ||
* After each `input` scheduled `output` will be destroyed and replaced with |
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 if this is clear, but it could be only me.
If multiple calls occur within as single
minInterval
time, the closest (soonest?) interval call will use the last passed arguments and discard arguments that were given in preceeding calls.
Aaaand looking at above ☝️ it doesn't look any better 😄 I think we'll need to ask other devs to help us out here. But it's crucial this bit is understandable, as it's a very important information.
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.
TBO I'm not sure if we need information about discarding arguments in preceding calls since preceding call (there is only one previously scheduled call) is discarded. However, I think that the sentence:
If multiple calls occur within a single
minInterval
time, the most recentinput
call with its arguments will be used to schedule nextoutput
call, and the previousoutput
call will be discarded.
best corresponds to how this function works. Although I'm not sure if it's enough understandable.
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 think it works well 👍
core/tools.js
Outdated
* After each `input` scheduled `output` will be destroyed and replaced with | ||
* new one. It gives you the opportunity to modify passed parameters into `input` function and get | ||
* different results. | ||
* |
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 think it make sense to put a note that the first call is always guaranteed to be executed synchronously.
core/tools.js
Outdated
* | ||
* buffer.input( 'foo!' ); | ||
* // 'foo!' logged immediately. | ||
* buffer.input( 'buz!' ); |
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.
The third word in foo bar used most commonly is baz
so let's stick to foo bar baz. 🙂 And you should reorder it here.
core/tools.js
Outdated
* new one. It gives you the opportunity to modify passed parameters into `input` function and get | ||
* different results. | ||
* | ||
* var buffer = CKEDITOR.tools.throttle( 200, function( message ) { |
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.
Listings should be wrapped with triple backticks + language hit 🙀
core/tools.js
Outdated
* @since 4.10.0 | ||
* @param {Number} minInterval Minimum interval between `output` calls in milliseconds. | ||
* @param {Function} output Function that will be executed as `output`. | ||
* @param {Object} [scopeObj] The object used to scope the listener call (the `this` object). |
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.
Technically it's not a scope… it's a context. There is a difference between the two (please have a read on it and don't repeat the mistakes that the Ancient Ones did 🙂). So context
or contextObj
and a proper docs updates.
tests/core/tools.js
Outdated
buffer.input( foo ); | ||
|
||
assert.areSame( 1, output ); | ||
assert.areSame( foo, message ); |
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.
Good luck with figuring out as any of the assertion fails. In other words, please, put meaningful assert messages when possible and applicable.
For sure this test case is one of them.
tests/core/tools.js
Outdated
buffer.input( foo ); | ||
|
||
assert.areSame( 2, output ); | ||
assert.areSame( buz, message ); |
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.
No reason to check the message here, as it couldn't be changed if the call count is the same.
CHANGES.md
Outdated
@@ -7,6 +7,7 @@ New Features: | |||
|
|||
* [#1761](https://github.com/ckeditor/ckeditor-dev/issues/1761): [Autolink](https://ckeditor.com/cke4/addon/autolink) plugin supports email links. | |||
* [#1703](https://github.com/ckeditor/ckeditor-dev/issues/1703): Introduced Mentions plugin providing autocompletion feature for usernames. | |||
* [#1993](https://github.com/ckeditor/ckeditor-dev/issues/1993): Added [`CKEDITOR.tools.throttle`](http://docs.ckeditor.com/ckeditor4/docs/#!/api/CKEDITOR_tools.html#method-throttle) 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.
It should land in the API section.
…rgument for throttled calls.
I have also pushed a single test case explicitly checking that the last argument is always used for throttled functions. |
tests/core/tools.js
Outdated
assert.isTrue( inputSpy.calledWithExactly( foo ), 'Call argument the after second call' ); | ||
|
||
wait( function() { | ||
assert.isTrue( inputSpy.calledOnce, 'Call count after the second call timeout (1st)' ); |
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.
This assertion does not display call count as it says. Actually I'd rather see that in the assertion, so:
assert.areSame( 1, inputSpy.callCount, 'Call count after the second call timeout (1st)' );
core/tools.js
Outdated
* Throttles `input` events (or any `input` calls) | ||
* and triggers `output` not more often than once per `minInterval`. | ||
* | ||
* After each `input` scheduled `output` will be destroyed and replaced with |
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 think it works well 👍
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.
Code looks much better, however you did not address one important point from review summary:
Some things to be resolved. On top of this this code is a copy and pasta from CKEDITOR.tools.eventBuffer we should refactor both methods to use a common code base.
We can extract it to a separate issue though.
The only thing that we need to work on are the docs. I'll adjust it in a following PR and I think we're good.
core/tools.js
Outdated
@@ -579,6 +579,95 @@ | |||
}, milliseconds || 0 ); | |||
}, | |||
|
|||
/** | |||
* Throttles `input` events (or any `input` calls) |
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.
It has nothing to do with events, we're talking about input
being a function here.
core/tools.js
Outdated
* @returns {Object} | ||
* @returns {Function} return.input Buffer's input method. | ||
* Accepts parameters which will be directly passed into `output` function. | ||
* @returns {Function} return.reset Resets buffered events — `output` will not be executed |
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.
Buffered events calls.
I have adjusted things that I was missing. Request from #1996 (review) extracted to #2045. |
What is the purpose of this pull request?
New feature
Does your PR contain necessary tests?
All patches which change the editor code must include tests. You can always read more
on PR testing,
how to set the testing environment and
how to create tests
in the official CKEditor documentation.
This PR contains
What changes did you make?
Added throttling function based on
CKEDITOR.tools.eventsBuffer
.Closes #1993