thenables.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  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. return hasProp.call(obj, "_promise0");
  46. }
  47. function doThenable(x, then, context) {
  48. var promise = new Promise(INTERNAL);
  49. var ret = promise;
  50. if (context) context._pushContext();
  51. promise._captureStackTrace();
  52. if (context) context._popContext();
  53. var synchronous = true;
  54. var result = util.tryCatch(then).call(x, resolve, reject);
  55. synchronous = false;
  56. if (promise && result === errorObj) {
  57. promise._rejectCallback(result.e, true, true);
  58. promise = null;
  59. }
  60. function resolve(value) {
  61. if (!promise) return;
  62. promise._resolveCallback(value);
  63. promise = null;
  64. }
  65. function reject(reason) {
  66. if (!promise) return;
  67. promise._rejectCallback(reason, synchronous, true);
  68. promise = null;
  69. }
  70. return ret;
  71. }
  72. return tryConvertToPromise;
  73. };