It turns out that because of the way that Royale binds methods, there’s no need to pass around “this” to these functions.
You can just do this: var foo:Foo = new Foo(); var increment:Function = debounceShort(foo.increment,30); And then happily call increment(n) and it’ll automatically just work on foo. B-) I also added a throttle function. Having fun with this! Harbs > On Jan 4, 2022, at 5:46 PM, Piotr Zarzycki <piotrzarzyck...@gmail.com> wrote: > > Hi Harbs, > > Great addition! > > wt., 4 sty 2022 o 16:17 Harbs <harbs.li...@gmail.com> napisał(a): > >> 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); >>> + } >>> + >>> + >>> + } >>> +} >> >> > > -- > > Piotr Zarzycki