Angular Broadcast Asynchronous Events Okay I have the following use case:

Module A broadcasts an event.
Module B listens to that event.
Maybe also Module C listens to that event.

Now Module B has to perform an asynchronous operation before Module A may proceed with its code.

I solved this by creating an custom module $deferredEvents which allows to queue up asynchronous tasks before proceeding.

Example: http://jsfiddle.net/68845rw4/

Module:

angular.module('deferredEvents', []).provider('$deferredEvent', function () {
  this.$get = function ($q) {
    /**
     *  @param type String - 'broadcast' | 'emit'
     *  @param $scope Scope
     *  @param eventName String - name of the event
     */
    return function $deferredEvent(type, $scope, eventName) {
      var queueHelper = {
        queue: [],
        promise: $q.when(),
        /**
         * Promise will be executed after all previous promisses passed
         */
        appendThen: function appendThen () {
          return this.queuePromise(this.promise.then.apply(this.promise, arguments));
        },
        /**
         * Promise will be executed immediately
         */
        queuePromise: function queuePromise (promise) {
          if (promise === this.promise) {
            throw new Error('Can\'t wait for own promise');
          }
          // Execute promise
          promise = $q.when(promise);
          // Add the promise result to the queue
          this.promise = this.promise.then(function () {
            return promise;
          });
          return this.promise;
        }
      };
      var args = Array.prototype.slice.call(arguments, 3);
      var emitArgs = [eventName, queueHelper].concat(args);
      var event = $scope['$' + type].apply($scope, emitArgs);
      return queueHelper.promise.then(function() {
          return $q.all(queueHelper.queue);
        }).then(function (results) {
          var failed = results.some(function (val) {
            return val === false;
          });
          return failed ? $q.reject(event) : event;
        }, function () {
          return $q.reject(event);
        });
    };
  };
}).provider('$deferredEmit', function () {
  this.$get = function ($deferredEvent) {
    return function $deferredEmit($scope, eventName) {
      return $deferredEvent.apply(this, ['emit', $scope, eventName].concat(Array.prototype.slice.call(arguments, 2)));
    };
  };
}).provider('$deferredBroadcast', function () {
  this.$get = function ($deferredEvent) {
    return function $deferredBroadcast($scope, eventName) {
      return $deferredEvent.apply(this, ['broadcast', $scope, eventName].concat(Array.prototype.slice.call(arguments, 2)));
    };
  };
});
Idea seems nice but for me it's quite hard to follow. Don't get me wrong, it might just be me!

But could you achieve the same functionality A proceeds when B has done it's thing just by passing a callback function in your broadcasted/emitted event?

angular.module('moduleA', ['moduleB'])
  .controller('OneCtrl', function($scope, $rootScope) {
    // broadcast event
    $scope.send = function() {
      console.log('broadcast event');
      $rootScope.$broadcast('event:my-event', callback);
    };

    // event callback
    var callback = function(result) {
      console.log('callback', result);
    };
  }); 

angular.module('moduleB',[])
  .controller('TheOtherCtrl', function($scope, $q, $timeout) {
    // receive event
    $scope.$on('event:my-event', function(event, callback) {
      console.log('received', event.name);
      // execute callback with process result
      process(true).then(callback, callback);
    });

    // some async processing
    function process(success) {
      return  $timeout(function() {
        return success ? $q.when(true) : $q.reject(false);
      }, 800);
    }
  });



  broadcast event
  received event:my-event
  callback true