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);
> +        }
> +
> +
> +    }
> +}

Reply via email to