thenables.js (2131B)
1 "use strict"; 2 module.exports = function(Promise, INTERNAL) { 3 var util = require("./util"); 4 var errorObj = util.errorObj; 5 var isObject = util.isObject; 6 7 function tryConvertToPromise(obj, context) { 8 if (isObject(obj)) { 9 if (obj instanceof Promise) return obj; 10 var then = getThen(obj); 11 if (then === errorObj) { 12 if (context) context._pushContext(); 13 var ret = Promise.reject(then.e); 14 if (context) context._popContext(); 15 return ret; 16 } else if (typeof then === "function") { 17 if (isAnyBluebirdPromise(obj)) { 18 var ret = new Promise(INTERNAL); 19 obj._then( 20 ret._fulfill, 21 ret._reject, 22 undefined, 23 ret, 24 null 25 ); 26 return ret; 27 } 28 return doThenable(obj, then, context); 29 } 30 } 31 return obj; 32 } 33 34 function doGetThen(obj) { 35 return obj.then; 36 } 37 38 function getThen(obj) { 39 try { 40 return doGetThen(obj); 41 } catch (e) { 42 errorObj.e = e; 43 return errorObj; 44 } 45 } 46 47 var hasProp = {}.hasOwnProperty; 48 function isAnyBluebirdPromise(obj) { 49 try { 50 return hasProp.call(obj, "_promise0"); 51 } catch (e) { 52 return false; 53 } 54 } 55 56 function doThenable(x, then, context) { 57 var promise = new Promise(INTERNAL); 58 var ret = promise; 59 if (context) context._pushContext(); 60 promise._captureStackTrace(); 61 if (context) context._popContext(); 62 var synchronous = true; 63 var result = util.tryCatch(then).call(x, resolve, reject); 64 synchronous = false; 65 66 if (promise && result === errorObj) { 67 promise._rejectCallback(result.e, true, true); 68 promise = null; 69 } 70 71 function resolve(value) { 72 if (!promise) return; 73 promise._resolveCallback(value); 74 promise = null; 75 } 76 77 function reject(reason) { 78 if (!promise) return; 79 promise._rejectCallback(reason, synchronous, true); 80 promise = null; 81 } 82 return ret; 83 } 84 85 return tryConvertToPromise; 86 };