FYI:

This commit adds easy conversion between the Promise paradigm and the Task 
paradigm.

I’ve taken to coding using AsyncTasks for pretty much all my async code. It has 
greatly improved code readability. But sometimes it’s necessary to convert 
between tasks and promises — especially when dealing with third party libraries.

taskToPromise and promiseToTask fill that need.

taskToPromise(someTask).then(function(result){
        // do something with a promise result
});

or if you need to return a promise and are using tasks:
 return taskToPromise(someTask)

For the reverse when you get a promise from some code and want to use it with 
tasks (i.e. CompoundAsyncTask or similar):

var task:PromiseTask  = promiseToTask(promise);

HTH,
Harbs

> On Nov 27, 2022, at 2:06 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 2d03e910a1 Added taskToPromise and promiseToTask
> 2d03e910a1 is described below
> 
> commit 2d03e910a17286a6479019be0f828fda7dc62878
> Author: Harbs <ha...@in-tools.com>
> AuthorDate: Sun Nov 27 14:06:13 2022 +0200
> 
>    Added taskToPromise and promiseToTask
> ---
> .../projects/Core/src/main/royale/CoreClasses.as   |   3 +
> .../org/apache/royale/utils/async/PromiseTask.as   |  76 +++++++++++
> .../org/apache/royale/utils/async/promiseToTask.as |  35 ++++++
> .../org/apache/royale/utils/async/taskToPromise.as |  47 +++++++
> .../src/test/royale/flexUnitTests/CoreTester.as    |   1 +
> .../src/test/royale/flexUnitTests/TaskTests.as     | 139 +++++++++++++++++++++
> 6 files changed, 301 insertions(+)
> 
> diff --git a/frameworks/projects/Core/src/main/royale/CoreClasses.as 
> b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> index b5a6d3f13f..3b451f72dc 100644
> --- a/frameworks/projects/Core/src/main/royale/CoreClasses.as
> +++ b/frameworks/projects/Core/src/main/royale/CoreClasses.as
> @@ -373,6 +373,9 @@ internal class CoreClasses
> 
>       import org.apache.royale.utils.async.CompoundAsyncTask; 
> CompoundAsyncTask;
>       import org.apache.royale.utils.async.SequentialAsyncTask; 
> SequentialAsyncTask;
> +     import org.apache.royale.utils.async.PromiseTask; PromiseTask;
> +     import org.apache.royale.utils.async.taskToPromise; taskToPromise;
> +     import org.apache.royale.utils.async.promiseToTask; promiseToTask;
> 
>       import org.apache.royale.utils.css.addDynamicSelector; 
> addDynamicSelector;
> 
> diff --git 
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/PromiseTask.as
>  
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/PromiseTask.as
> new file mode 100644
> index 0000000000..6460126a6b
> --- /dev/null
> +++ 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/PromiseTask.as
> @@ -0,0 +1,76 @@
> +////////////////////////////////////////////////////////////////////////////////
> +//
> +//  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.async
> +{
> +     /**
> +      * A PromiseTask takes a promise and only resolves the promise when
> +      * run is called on the task.   This is useful for deferring the
> +      * resolution of a promise until some other event occurs.
> +      * 
> +      * It's also usefult for converting a Promise for task-based code.
> +      * The PromiseTask can be used in a Compound or SequentialTask
> +      * which normally would not work with promises.
> +      * 
> +      * @langversion 3.0
> +      * @productversion Royale 0.9.10
> +      */
> +     public class PromiseTask extends AsyncTask
> +     {
> +             public function PromiseTask(promise:Promise)
> +             {
> +                     _promise = promise;
> +             }
> +             private var _promise:Promise;
> +
> +             /**
> +              * The result of the promise.
> +              * 
> +              * @langversion 3.0
> +              * @productversion Royale 0.9.10
> +              */
> +             public var result:*;
> +
> +             /**
> +              * The error of the promise.
> +              * 
> +              * @langversion 3.0
> +              * @productversion Royale 0.9.10
> +              */
> +             public var error:*;
> +             
> +             override public function run(data:Object=null):void
> +             {
> +                     if(data != null)
> +                             this.data = data;
> +
> +                     _promise.then(
> +                             function(res:*):void
> +                             {
> +                                     result = res;
> +                                     complete();
> +                             },
> +                             function(err:*):void
> +                             {
> +                                     error = err;
> +                                     fail();
> +                             }
> +                     );
> +             }
> +     }
> +}
> \ No newline at end of file
> diff --git 
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/promiseToTask.as
>  
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/promiseToTask.as
> new file mode 100644
> index 0000000000..083a82010b
> --- /dev/null
> +++ 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/promiseToTask.as
> @@ -0,0 +1,35 @@
> +////////////////////////////////////////////////////////////////////////////////
> +//
> +//  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.async
> +{
> +     /**
> +      * Utility function which takes a Promise and returns a PromiseTask
> +      * The task completes when the Promise resolves and fails when the 
> Promise rejects.
> +      * 
> +      * Useful for using Promises in task based code.
> +      * 
> +      * @langversion 3.0
> +      * @productversion Royale 0.9.10
> +      * 
> +      */
> +     public function promiseToTask(promise:Promise):PromiseTask
> +     {
> +             return new PromiseTask(promise);                
> +     }
> +}
> \ No newline at end of file
> diff --git 
> a/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/taskToPromise.as
>  
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/taskToPromise.as
> new file mode 100644
> index 0000000000..2b0410c185
> --- /dev/null
> +++ 
> b/frameworks/projects/Core/src/main/royale/org/apache/royale/utils/async/taskToPromise.as
> @@ -0,0 +1,47 @@
> +////////////////////////////////////////////////////////////////////////////////
> +//
> +//  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.async
> +{
> +     /**
> +      * Utility function which takes a IAsyncTask and returns a Promise 
> which 
> +      * resolves when the task completes or rejects if the task fails.
> +      * 
> +      * Useful for converting IAsyncTask to Promise based APIs.
> +      * 
> +      * @langversion 3.0
> +      * @productversion Royale 0.9.10
> +      * 
> +      */
> +     public function taskToPromise(task:IAsyncTask):Promise
> +     {
> +             var promise:Promise = new Promise(function(resolve:Function, 
> reject:Function):void
> +             {
> +                     task.done(function(task:IAsyncTask):void
> +                     {
> +                             if(task.completed)
> +                                     resolve(task.data);
> +
> +                             else
> +                                     reject(task.data);
> +
> +                     });
> +             });
> +             return promise;
> +     }
> +}
> \ 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 eeb4e76e4b..b95cb19307 100644
> --- a/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> +++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/CoreTester.as
> @@ -46,6 +46,7 @@ package flexUnitTests
>         public var eventsTest:EventsTest;
>         public var objectUtilTests:ObjectUtilsTest;
>         public var functionalTests:FunctionalTests;
> +        public var taskTests:TaskTests;
> 
>     }
> }
> diff --git 
> a/frameworks/projects/Core/src/test/royale/flexUnitTests/TaskTests.as 
> b/frameworks/projects/Core/src/test/royale/flexUnitTests/TaskTests.as
> new file mode 100644
> index 0000000000..2422a902b6
> --- /dev/null
> +++ b/frameworks/projects/Core/src/test/royale/flexUnitTests/TaskTests.as
> @@ -0,0 +1,139 @@
> +////////////////////////////////////////////////////////////////////////////////
> +//
> +//  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
> +{
> +
> +     import org.apache.royale.test.asserts.*;
> +     import org.apache.royale.test.async.*;
> +     import org.apache.royale.functional.*;
> +     import org.apache.royale.functional.decorator.*;
> +     import org.apache.royale.test.asserts.assertTrue;
> +     import org.apache.royale.test.asserts.assertEquals;
> +     import org.apache.royale.utils.async.promiseToTask;
> +     import org.apache.royale.utils.async.PromiseTask;
> +     import org.apache.royale.utils.async.AsyncTask;
> +     import org.apache.royale.utils.async.taskToPromise;
> +     import org.apache.royale.test.asserts.assertNotEquals;
> +     
> +     public class TaskTests
> +     {               
> +                     [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="50")]
> +                     public function testPromiseToTask():void
> +                     {
> +                             var resolvePromise:Promise = new 
> Promise(function(resolve:Function, reject:Function):void{
> +                                     resolve("resolved");
> +                             });
> +                             var resolvedTask:PromiseTask = 
> promiseToTask(resolvePromise);
> +                             
> resolvedTask.done(function(task:PromiseTask):void{
> +                                     assertEquals(task.result, "resolved");
> +                             });
> +                             resolvedTask.run();
> +
> +                             var rejectedPromise:Promise = new 
> Promise(function(resolve:Function, reject:Function):void{
> +                                     reject("rejected");
> +                             });
> +                             var rejectedTask:PromiseTask = 
> promiseToTask(rejectedPromise);
> +                             
> rejectedTask.done(function(task:PromiseTask):void{
> +                                     assertEquals(task.error, "rejected");
> +                             });
> +                             rejectedTask.run();
> +                     }
> +
> +                     [Test(async,timeout="300")]
> +                     public function testTaskToPromise():void
> +                     {
> +                             var completeTask:AsyncTask = new CompleteTask();
> +                             var completePromise:Promise = 
> taskToPromise(completeTask);
> +                             var failTask:AsyncTask = new FailTask();
> +                             var promiseFailed:Boolean;
> +                             var promiseCompleted:Boolean;
> +                             
> taskToPromise(completeTask).then(function(result:*):void{
> +                                     promiseCompleted = true;
> +                                     // trace('assertEquals(result, 
> "completed");');
> +                                     // assertEquals(result, "completed");
> +                             }, function(error:*):void{
> +                                     promiseCompleted = false;
> +                                     // trace('assertTrue(false, "should not 
> be called");')
> +                                     // assertTrue(false, "should not be 
> called");
> +                             });
> +                             
> taskToPromise(failTask).then(function(result:*):void{
> +                                     promiseFailed = false;
> +                                     // trace('assertTrue(false, "should not 
> be called");')
> +                                     // assertTrue(false, "should not be 
> called");
> +                             }, function(error:*):void{
> +                                     promiseFailed = true;
> +                                     // trace('assertEquals(error, 
> "failed");');
> +                                     // assertEquals(error, "failed");
> +                             });
> +                             completeTask.run();
> +                             failTask.run();
> +
> +                                     Async.delayCall(this, function():void
> +                                     {
> +                                                     
> assertTrue(promiseCompleted,"Promise should complete");
> +                                                     
> assertTrue(promiseFailed,"Promise should fail");
> +                                     }, 200);
> +                     }
> +
> +     }
> +}
> +import org.apache.royale.utils.async.AsyncTask;
> +
> +class CompleteTask extends AsyncTask
> +{
> +     public function CompleteTask()
> +     {
> +             super();
> +     }
> +     override public function run(data:Object=null):void{
> +             this.data = "completed";
> +             complete();
> +     }
> +}
> +class FailTask extends AsyncTask
> +{
> +     public function FailTask()
> +     {
> +             super();
> +     }
> +     override public function run(data:Object=null):void{
> +             this.data = "failed";
> +             fail();
> +     }
> +}
> \ No newline at end of file
> 

Reply via email to