index.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. var isPromise = require('is-promise')
  2. var nextTick;
  3. if (typeof setImediate === 'function') nextTick = setImediate
  4. else if (typeof process === 'object' && process && process.nextTick) nextTick = process.nextTick
  5. else nextTick = function (cb) { setTimeout(cb, 0) }
  6. var extensions = [];
  7. module.exports = Promise
  8. function Promise(fn) {
  9. if (!(this instanceof Promise)) {
  10. return typeof fn === 'function' ? new Promise(fn) : defer()
  11. }
  12. var isResolved = false
  13. var isFulfilled = false
  14. var value
  15. var waiting = []
  16. var running = false
  17. function next(skipTimeout) {
  18. if (waiting.length) {
  19. running = true
  20. waiting.shift()(skipTimeout || false)
  21. } else {
  22. running = false
  23. }
  24. }
  25. this.then = then;
  26. function then(cb, eb) {
  27. return new Promise(function (resolver) {
  28. function done(skipTimeout) {
  29. var callback = isFulfilled ? cb : eb
  30. if (typeof callback === 'function') {
  31. function timeoutDone() {
  32. var val;
  33. try {
  34. val = callback(value)
  35. } catch (ex) {
  36. resolver.reject(ex)
  37. return next()
  38. }
  39. resolver.fulfill(val);
  40. next(true);
  41. }
  42. if (skipTimeout) timeoutDone()
  43. else nextTick(timeoutDone)
  44. } else if (isFulfilled) {
  45. resolver.fulfill(value)
  46. next(skipTimeout)
  47. } else {
  48. resolver.reject(value)
  49. next(skipTimeout)
  50. }
  51. }
  52. waiting.push(done)
  53. if (isResolved && !running) next()
  54. });
  55. }
  56. (function () {
  57. function fulfill(val) {
  58. if (isResolved) return
  59. if (isPromise(val)) val.then(fulfill, reject)
  60. else {
  61. isResolved = isFulfilled = true
  62. value = val
  63. next()
  64. }
  65. }
  66. function reject(err) {
  67. if (isResolved) return
  68. isResolved = true
  69. isFulfilled = false
  70. value = err
  71. next()
  72. }
  73. var resolver = {fulfill: fulfill, reject: reject};
  74. for (var i = 0; i < extensions.length; i++) {
  75. extensions[i](this, resolver);
  76. }
  77. if (typeof fn === 'function') {
  78. try {
  79. fn(resolver)
  80. } catch (ex) {
  81. resolver.reject(ex);
  82. }
  83. }
  84. }());
  85. }
  86. function defer() {
  87. var resolver
  88. var promise = new Promise(function (res) { resolver = res })
  89. return {resolver: resolver, promise: promise}
  90. }
  91. Promise.use = function (extension) {
  92. extensions.push(extension);
  93. };