Checking if an object is a promising function

2019-02-19 08:54发布

问题:

In protractor.js,

I have functions that promise/defer. For example

var myFunc = function(_params) {
  var deferred = protractor.promise.defer();
  /***do magical code things****/
  /***wait for other promises***/
  /*****deferred.fulfill();*****/
  return deferred.promise;
};

What sort of combinations of typeof statements can I use to check if this thing (when passed to something else) promises?

  • typeof promiseMaybe === 'function'
  • typeof promiseMaybe.then === 'function'
    • &&'ed with prior?

Or is there a non-typeof function like...

  • promiseMaybe.isThenable
  • protractor.promise.isThenable(promiseMaybe)

Clarification

I have a method that will receive myFunc as a parameter, but this method can also receive strings and finders. I need to know how to tell if a parameter is the function that promises something, possibly before calling the function.

回答1:

There is a helper method in Protractor for that - protractor.promise.isPromise():

var el = element(by.css('foo'));

protractor.promise.isPromise('foo'); // false
protractor.promise.isPromise(el); // false
protractor.promise.isPromise(el.click()); // true

Protractor takes this method directly from selenium-webdriver, here you can find the source code of the method:

/**
 * Determines whether a {@code value} should be treated as a promise.
 * Any object whose "then" property is a function will be considered a promise.
 *
 * @param {*} value The value to test.
 * @return {boolean} Whether the value is a promise.
 */
promise.isPromise = function(value) {
  return !!value && goog.isObject(value) &&
      // Use array notation so the Closure compiler does not obfuscate away our
      // contract. Use typeof rather than goog.isFunction because
      // goog.isFunction accepts instanceof Function, which the promise spec
      // does not.
      typeof value['then'] === 'function';
};

So basically, any object with a then method is considered a Promise.