0

In Angular.js library, we have an api $q,

$q.all() accepts promise array, i.e.

$q.all([promise1,promise2,....,promiseN]).then(function);

The callback function is resolved only after all the promises passed in arguments are resolved,

As you can see in the below code,

        <script type="text/javaScript">
        angular.module("myApp",[]);
        angular.module("myApp").controller("myCtrl",myCtrl);
        angular.module("myApp").factory("demoService",demoService);

        myCtrl.$inject = ["$scope","demoService","$q"];
        demoService.$inject = ["$q","$timeout"];

        function myCtrl($scope,demoService,$q){
            $scope.message = "All promises";

            $scope.init = init;


            function invokedAll(){
                var promises = [demoService.get(1),
                                demoService.get(2),
                                demoService.get(3),
                                demoService.get(4),
                                demoService.get(5),
                                demoService.get(6),
                                demoService.get(7),
                                demoService.get(8),
                                demoService.get(9),
                                demoService.get(10)];

                return $q.all(promises);                
            } //invokedAll

            function init(){
                invokedAll().then(function(){
                    console.log(" Data loaded successfully ");
                });
            }
        }

        function demoService($q,$timeout){
            var TIMEOUT = 2000; // 5 seconds
            return {
                get : function(messageNo){
                    TIMEOUT += 1000;
                    var deferred = $q.defer();
                    $timeout(function(){
                        console.log("data loaded "+messageNo);
                        deferred.resolve("success");
                    },TIMEOUT);

                    return deferred.promise;
                }
            };
        }   
    </script>
    <body ng-controller="myCtrl" ng-init="init()">

The output of above code is,

data loaded 1
data loaded 2
data loaded 3
data loaded 4
data loaded 5
data loaded 6
data loaded 7
data loaded 8
data loaded 9
data loaded 10
Data loaded successfully

You can see that the final line is printed only after all the promises are resolved.

The same above feature I tried to implement in java,

I am using ExecuterService api to execute tasks in threadpool.

And once all the tasks are executed, invoke the final.

the code is as follows,

 package executerService.example01;

 public class Example05 {
   private static final int POOL_COUNT = 10;

   private static void tasks() throws Exception{
      ExecutorService service = null;
      Set<Callable<Integer>> callables = null;
      List<Future<Integer>> futures = null;

      service = Executors.newFixedThreadPool(POOL_COUNT);

      callables = new HashSet<Callable<Integer>>();

      callables.add(new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            int taskNo = 1;
            System.out.println(Thread.currentThread().getName()+", TASK-NO "+taskNo);
            return taskNo;
        }

      });

      callables.add(new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            int taskNo = 2;
            System.out.println(Thread.currentThread().getName()+", TASK-NO "+taskNo);
            return taskNo;
        }

     });

     callables.add(new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
            int taskNo = 3;
            System.out.println(Thread.currentThread().getName()+", TASK-NO "+taskNo);
            return taskNo;
        }

     });


    futures = service.invokeAll(callables);


    for(Iterator<Future<Integer>> itr = futures.iterator(); itr.hasNext();){
        System.out.println("Execution of Task No "+itr.next().get()+" completed");
    }
  } //end of method task


  public static void main(String [] args){
      ExecutorService service = null;
      Future<Boolean> future = null;
      try{          
        service = Executors.newSingleThreadExecutor();

        future = service.submit(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                tasks();
                return true;
            }

        });

        if(future.get()){
            System.out.println("All the tasks are executed");
        }
      }catch(Exception e){
        e.printStackTrace();
      }
  } // end of main method
}

In the above java code you can see,

method 'tasks' creates 3 tasks using 'callable' instance, and all the 3 tasks are invoked using "invokeAll" method of ExecuterService.

Once all tasks are executed, the final Future instances is invoked in main method where it returns true,

the output of the above java code is as follows,

pool-2-thread-1, TASK-NO 2
pool-2-thread-2, TASK-NO 1
pool-2-thread-3, TASK-NO 3
Execution of Task No 2 completed
Execution of Task No 1 completed
Execution of Task No 3 completed
All the tasks are executed

My question is

whether I am able to achieve the same behavior of '$q.all()' of angular.js
in Java using 'ExecuterService.invokeAll()' and 'Future.get()' ?

Please guide me if my understanding is write.

Also let me know, whether the above implementation in Java is correct or can be implemented in different way.

Rahul Shivsharan
  • 2,481
  • 7
  • 40
  • 59
  • 1
    what behaviour? output is kinda same, no? Also remember that js is one thread, promises may look like java threads, but actually it is totally different. – Petr Averyanov Apr 05 '17 at 12:06
  • 1
    I'd recommend to look rather at CompletableFuture if you can use Java8. They even provide an allOf-method which should bring you pretty close to the behavior for JS, but as Petr said there will always be some semantic differences – Bernd Ebertz Apr 05 '17 at 16:00

0 Answers0