|
248 | 248 | };
|
249 | 249 |
|
250 | 250 | /**
|
251 |
| - * Decide somewhat-naively if something is a Thenable. |
| 251 | + * Decide somewhat-naively if something is a Thenable. Matches Promises A+ Spec, section 1.2 “thenable” is an object or function that defines a then method." |
252 | 252 | * @param elem {*} object to inspect
|
253 | 253 | * @return {Boolean} is `elem` a Thenable?
|
254 | 254 | */
|
255 | 255 | dust.isThenable = function(elem) {
|
256 |
| - return elem && |
257 |
| - typeof elem === 'object' && |
| 256 | + return elem && /* Beware: `typeof null` is `object` */ |
| 257 | + (typeof elem === 'object' || typeof elem === 'function') && |
258 | 258 | typeof elem.then === 'function';
|
259 | 259 | };
|
260 | 260 |
|
| 261 | + /** |
| 262 | + * Decide if an element is a function but not Thenable; it is prefereable to resolve a thenable function by its `.then` method. |
| 263 | + * @param elem {*} target of inspection |
| 264 | + * @return {Boolean} is `elem` a function without a `.then` property? |
| 265 | + */ |
| 266 | + dust.isNonThenableFunction = function(elem) { |
| 267 | + return typeof elem === 'function' && !dust.isThenable(elem); |
| 268 | + }; |
| 269 | + |
261 | 270 | /**
|
262 | 271 | * Decide very naively if something is a Stream.
|
263 | 272 | * @param elem {*} object to inspect
|
|
430 | 439 | }
|
431 | 440 | }
|
432 | 441 |
|
433 |
| - if (typeof ctx === 'function') { |
| 442 | + if (dust.isNonThenableFunction(ctx)) { |
434 | 443 | fn = function() {
|
435 | 444 | try {
|
436 | 445 | return ctx.apply(ctxThis, arguments);
|
|
747 | 756 | };
|
748 | 757 |
|
749 | 758 | Chunk.prototype.reference = function(elem, context, auto, filters) {
|
750 |
| - if (typeof elem === 'function') { |
| 759 | + if (dust.isNonThenableFunction(elem)) { |
751 | 760 | elem = elem.apply(context.current(), [this, context, null, {auto: auto, filters: filters}]);
|
752 | 761 | if (elem instanceof Chunk) {
|
753 | 762 | return elem;
|
|
772 | 781 | chunk = this,
|
773 | 782 | i, len, head;
|
774 | 783 |
|
775 |
| - if (typeof elem === 'function' && !dust.isTemplateFn(elem)) { |
| 784 | + if (dust.isNonThenableFunction(elem) && !dust.isTemplateFn(elem)) { |
776 | 785 | try {
|
777 | 786 | elem = elem.apply(context.current(), [this, context, bodies, params]);
|
778 | 787 | } catch(err) {
|
|
0 commit comments