code: function then(opt_callback, opt_errback) {
      // Avoid unnecessary allocations if we weren't given any callback functions.
      if (!opt_callback && !opt_errback) {
        return promise;
      }
  
      // The moment a listener is registered, we consider this deferred to be
      // handled; the callback must handle any rejection errors.
      handled = true;
      if (pendingRejectionKey) {
        flow.pendingRejections_ -= 1;
        flow.timer.clearTimeout(pendingRejectionKey);
      }
  
      var deferred = new webdriver.promise.Deferred(cancel, flow);
      var listener = {
        callback: opt_callback,
        errback: opt_errback,
        fulfill: deferred.fulfill,
        reject: deferred.reject
      };
  
      if (state == webdriver.promise.Deferred.State_.PENDING ||
          state == webdriver.promise.Deferred.State_.BLOCKED) {
        listeners.push(listener);
      } else {
        notify(listener);
      }
  
      return deferred.promise;
    }
docs: Registers a callback on this Deferred.
  
  @param {?(function(T): (R|webdriver.promise.Promise.<R>))=} opt_callback .
  @param {?(function(*): (R|webdriver.promise.Promise.<R>))=} opt_errback .
  @return {!webdriver.promise.Promise.<R>} A new promise representing the
  result of the callback.
  @template R
  @see webdriver.promise.Promise#then