thenables.js 2.1 KB

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