Opened 7 years ago

Closed 7 years ago

#15904 closed enhancement (wontfix)

An optional "priority" parameter to topic.subscribe()

Reported by: Mischan Gholizadeh Toosarani Owned by:
Priority: undecided Milestone: tbd
Component: General Version: 1.8.0
Keywords: Cc:
Blocked By: Blocking:

Description

Is there any interest in having an optional priority parameter in topic.subscribe()?

In situations where many subscribe, it sometimes happens that there are execution-order issues. The first who subscribes is also the first to be informed of the event (afaik). A few use-cases could be solved without synchronization (which also couples tighter), if subscription-callbacks would be called by priority.

Change History (1)

comment:1 Changed 7 years ago by ben hockey

Resolution: wontfix
Status: newclosed

generally, in the core of dojo, we try to provide very general building blocks that can either be used "as is" or extended/enhanced to add extra functionality. we prefer to provide features that are going to be most generally applicable and leave the "added extras" to the end user since this is where needs are more likely to vary from user to user.

topic.subscribe is a basic API that provides a simple way for pieces of code to pass messages in a decoupled way. to me, the idea of a priority queue starts to imply some coupling even if it's not as explicit as direct references. for example, let's say that you register something with priority 20, for another handler to get called before that one, it needs to register with a higher priority which then implies that it needs to know that something is already registered with priority 20. so the priority queue lets you register callbacks in a different order to what they will be called but now there is an implicit coupling where the programmer needs to know the priority of other handlers so that they can be ordered as desired by the programmer.

with that said though, there are ways you could implement something that might suit your needs.

you could publish "topic-pre" and "topic-post" topics whenever "topic" is published

define(['dojo/topic', 'dojo/aspect'], function (topic, aspect) {
  aspect.around(topic, 'publish', function (publish) {
    return function () {
      var args = [].slice.call(arguments);
      var topic = args.shift();
      publish.apply(this, [topic + '-pre'].concat(args));
      var ret = publish.apply(this, arguments);
      publish.apply(this, [topic + '-post'].concat(args));
      return ret;
    };
  });
});

you could even get more elaborate and implement a topic.intercept that allowed interceptors to be registered for a topic that could then apply logic to conditionally proceed with the publish.

define(['dojo/topic', 'dojo/aspect'], function (topic, aspect) {
  topic.intercept = function (topic, interceptor) {
    var interceptors = this._interceptors[topic] || (this._interceptors[topic] = []);
    interceptors.push(interceptor);
  };

  aspect.around(topic, 'publish', function (publish) {
    return function (topic) {
      var interceptors = this._interceptors[topic];

      // do stuff with the interceptors... then call publish if interceptors allow it

    };
  });
});

...or you could write your own priority queue based publishing module and use that instead of dojo/topic.

Note: See TracTickets for help on using tickets.