thenables.js 2.4 KB

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