FYI: “Debounce” is a term that AFAIK was made popular by underscore. https://underscorejs.org/#debounce
There’s debounceLong which does the same thing as underscore’s default debounce functionality. Royale's version also has the option to pass in a “this” object. That’s necessary if you are debouncing a instance method which needs access to “this”. debounceShort is the same as debounceLong, but it debounces early like the “immediate” option in underscore’s version. I needed this functionality today, so I figured it’s time to start populating functional utilities… ;-) There’s “FunctionalTests” which show how to use it (sort of). HTH, Harbs > On Jan 4, 2022, at 5:10 PM, ha...@apache.org wrote: > > This is an automated email from the ASF dual-hosted git repository. > > harbs pushed a commit to branch develop > in repository https://gitbox.apache.org/repos/asf/royale-asjs.git > > > The following commit(s) were added to refs/heads/develop by this push: > new 5ca3337 Added debounceShort and debounceLong > 5ca3337 is described below > > commit 5ca333774e1463569ec0f291a2d17fe924b1181f > Author: Harbs <ha...@in-tools.com> > AuthorDate: Tue Jan 4 17:10:10 2022 +0200 > > Added debounceShort and debounceLong > --- > .../projects/Core/src/main/royale/CoreClasses.as | 3 + > .../apache/royale/utils/functional/debounceLong.as | 49 +++++++++ > .../royale/utils/functional/debounceShort.as | 51 +++++++++ > .../src/test/royale/flexUnitTests/CoreTester.as | 1 + > .../test/royale/flexUnitTests/FunctionalTests.as | 120 +++++++++++++++++++++ > 5 files changed, 224 insertions(+) > > diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as > b/frameworks/projects/Core/src/main/royale/CoreClasses.as > index df3709e..289429e 100644 > --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as > +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as > @@ -379,6 +379,9 @@ internal class CoreClasses > > import org.apache.royale.utils.replaceBead; replaceBead; > > + import org.apache.royale.utils.functional.debounceLong; debounceLong; > + import org.apache.royale.utils.functional.debounceShort; debounceShort; > + > import org.apache.royale.core.TextLineMetrics; TextLineMetrics; > import org.apache.royale.utils.ClassSelectorList; ClassSelectorList; > > diff --git > a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceLong.as > > b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceLong.as > new file mode 100644 > index 0000000..46d2a7e > --- /dev/null > +++ > b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceLong.as > @@ -0,0 +1,49 @@ > +//////////////////////////////////////////////////////////////////////////////// > +// > +// Licensed to the Apache Software Foundation (ASF) under one or more > +// contributor license agreements. See the NOTICE file distributed with > +// this work for additional information regarding copyright ownership. > +// The ASF licenses this file to You under the Apache License, Version 2.0 > +// (the "License"); you may not use this file except in compliance with > +// the License. You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +// > +//////////////////////////////////////////////////////////////////////////////// > +package org.apache.royale.utils.functional > +{ > + COMPILE::SWF{ > + import flash.utils.setTimeout; > + import flash.utils.clearTimeout; > + } > + /** > + * Returns a debounced function to run after a delay. > + * If the function is invoked within the delay period, > + * the delay will be reset to start from the latest invocation of the > function. > + * > + * @royalesuppressexport > + * @langversion 3.0 > + * @productversion Royale 0.9.9 > + * > + */ > + public function debounceLong(method:Function, > delay:Number,thisArg:Object=null):Function > + { > + var timeoutRef:*; > + return function(...args):void > + { > + function callback():void > + { > + timeoutRef = null; > + method.apply(thisArg,args); > + } > + clearTimeout(timeoutRef); > + timeoutRef = setTimeout(callback, delay); > + } > + } > +} > \ No newline at end of file > diff --git > a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceShort.as > > b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceShort.as > new file mode 100644 > index 0000000..113b35b > --- /dev/null > +++ > b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/functional/debounceShort.as > @@ -0,0 +1,51 @@ > +//////////////////////////////////////////////////////////////////////////////// > +// > +// Licensed to the Apache Software Foundation (ASF) under one or more > +// contributor license agreements. See the NOTICE file distributed with > +// this work for additional information regarding copyright ownership. > +// The ASF licenses this file to You under the Apache License, Version 2.0 > +// (the "License"); you may not use this file except in compliance with > +// the License. You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +// > +//////////////////////////////////////////////////////////////////////////////// > +package org.apache.royale.utils.functional > +{ > + COMPILE::SWF{ > + import flash.utils.setTimeout; > + import flash.utils.clearTimeout; > + } > + /** > + * Returns a debounced function to run after a delay. > + * If the function is invoked within the delay period, > + * the delay will be from the first invocation of the function. > + * > + * @royalesuppressexport > + * @langversion 3.0 > + * @productversion Royale 0.9.9 > + * > + */ > + public function debounceShort(method:Function, > delay:Number,thisArg:Object=null):Function > + { > + var timeoutRef:*; > + return function(...args):void > + { > + function callback():void > + { > + timeoutRef = null; > + method.apply(thisArg,args); > + } > + if(timeoutRef == null) > + { > + timeoutRef = setTimeout(callback, delay); > + } > + } > + } > +} > \ No newline at end of file > diff --git > a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as > b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as > index a0fb801..7b15375 100644 > --- a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as > +++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as > @@ -45,6 +45,7 @@ package flexUnitTests > public var sanitizerTest:SanitizeTest; > public var eventsTest:EventsTest; > public var objectUtilTests:ObjectUtilsTest; > + public var functionelTests:FunctionalTests; > > } > } > diff --git > a/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as > b/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as > new file mode 100644 > index 0000000..10db0f2 > --- /dev/null > +++ > b/frameworks/projects/Core/src/test/royale/flexUnitTests/FunctionalTests.as > @@ -0,0 +1,120 @@ > +//////////////////////////////////////////////////////////////////////////////// > +// > +// Licensed to the Apache Software Foundation (ASF) under one or more > +// contributor license agreements. See the NOTICE file distributed with > +// this work for additional information regarding copyright ownership. > +// The ASF licenses this file to You under the Apache License, Version 2.0 > +// (the "License"); you may not use this file except in compliance with > +// the License. You may obtain a copy of the License at > +// > +// http://www.apache.org/licenses/LICENSE-2.0 > +// > +// Unless required by applicable law or agreed to in writing, software > +// distributed under the License is distributed on an "AS IS" BASIS, > +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. > +// See the License for the specific language governing permissions and > +// limitations under the License. > +// > +//////////////////////////////////////////////////////////////////////////////// > +package flexUnitTests > +{ > + COMPILE::SWF{ > + import flash.utils.setTimeout; > + } > + > + import org.apache.royale.test.asserts.*; > + import org.apache.royale.test.async.*; > + import org.apache.royale.utils.functional.*; > + > + public class FunctionalTests > + { > + [Before] > + public function setUp():void > + { > + } > + > + [After] > + public function tearDown():void > + { > + } > + > + [BeforeClass] > + public static function setUpBeforeClass():void > + { > + } > + > + [AfterClass] > + public static function tearDownAfterClass():void > + { > + } > + > + [Test(async,timeout="300")] > + public function testDebounceLong():void > + { > + var value:Number = 0; > + var foo = function(){ > + this.value = 0; > + this.increment = function(val:Number){ > + this.value+=val; > + } > + } > + var fooObj = new foo(); > + var thisDebounced:Function = > debounceLong(fooObj.increment,30,fooObj); > + setTimeout(thisDebounced, 10,5); > + setTimeout(thisDebounced, 10,4); > + setTimeout(thisDebounced, 10,3); > + setTimeout(thisDebounced, 10,2); > + setTimeout(thisDebounced, 10,1); > + function increment(val:Number){ > + value+=val; > + } > + var debounced:Function = debounceLong(increment,30); > + setTimeout(debounced, 10,5); > + setTimeout(debounced, 10,4); > + setTimeout(debounced, 10,3); > + setTimeout(debounced, 10,2); > + setTimeout(debounced, 10,1); > + Async.delayCall(this, function():void > + { > + assertTrue(fooObj.value == 1,"foo value should be > incremented by 1"); > + assertTrue(value == 1,"Should be incremented by 1"); > + }, 100); > + } > + > + [Test(async,timeout="300")] > + public function testDebounceShort():void > + { > + var foo = function(){ > + this.value = 0; > + this.increment = function(val:Number){ > + this.value+=val; > + } > + } > + var fooObj = new foo(); > + var thisDebounced:Function = > debounceShort(fooObj.increment,30,fooObj); > + setTimeout(thisDebounced, 10,5); > + setTimeout(thisDebounced, 10,4); > + setTimeout(thisDebounced, 10,3); > + setTimeout(thisDebounced, 10,2); > + setTimeout(thisDebounced, 10,1); > + > + var value:Number = 0; > + function increment(val:Number){ > + value+=val; > + } > + var debounced:Function = debounceShort(increment,30); > + setTimeout(debounced, 10,5); > + setTimeout(debounced, 10,4); > + setTimeout(debounced, 10,3); > + setTimeout(debounced, 10,2); > + setTimeout(debounced, 10,1); > + Async.delayCall(this, function():void > + { > + assertTrue(fooObj.value > 1,"foo value should be greater > than 1"); > + assertTrue(value > 1,"Should be greater than 1"); > + }, 100); > + } > + > + > + } > +}