code: function subscribe(name, id, callback, timeout, failswitch) {
          if (typeof name !== s_string) {
              throw new TypeError('topic name must be a string.');
          }
          if (id === undefined || id === null) {
              if (typeof callback === s_function) {
                  id = callback;
              }
              else {
                  throw new TypeError('callback must be a function.');
              }
          }
          if (!_topics[name]) {
              _topics[name] = Object.create(null);
          }
          if (typeof id === s_function) {
              timeout = callback;
              callback = id;
              autoId().then(function(id) {
                  subscribe(name, id, callback, timeout, failswitch);
              });
              return;
          }
          if (typeof callback !== s_function) {
              throw new TypeError('callback must be a function.');
          }
          if (Future.isPromise(id)) {
              id.then(function(id) {
                  subscribe(name, id, callback, timeout, failswitch);
              });
              return;
          }
          // Default subscribe timeout is 5 minutes.
          if (timeout === undefined) { timeout = 300000; }
          var topic = getTopic(name, id);
          if (topic === null) {
              var cb = function() {
                  _invoke(self, name, [id, topic.handler, cb, {
                      idempotent: true,
                      failswitch: failswitch,
                      timeout: timeout
                  }], false);
              };
              topic = {
                  handler: function(result) {
                      var topic = getTopic(name, id);
                      if (topic) {
                          if (result !== null) {
                              var callbacks = topic.callbacks;
                              for (var i = 0, n = callbacks.length; i < n; ++i) {
                                  try {
                                      callbacks[i](result);
                                  }
                                  catch (e) {}
                              }
                          }
                          if (getTopic(name, id) !== null) { cb(); }
                      }
                  },
                  callbacks: [callback]
              };
              _topics[name][id] = topic;
              cb();
          }
          else if (topic.callbacks.indexOf(callback) < 0) {
              topic.callbacks.push(callback);
          }
      }
docs: subscribe(name, callback, timeout, failswitch) subscribe(name, id, callback, timeout, failswitch)