Guest User

Untitled

a guest
Dec 12th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.90 KB | None | 0 0
  1. const PENDING = 'pending';
  2. const FULFILLED = 'fulfilled';
  3. const REJECTED = 'rejected';
  4.  
  5. class Waiter {
  6. constructor (callback) {
  7. this.accept = this.accept.bind(this);
  8. this.reject = this.reject.bind(this);
  9. this.state = PENDING;
  10. this.successCallbacks = [];
  11. this.failureCallbacks = [];
  12. this.isWaiter = true;
  13. this.value = null;
  14.  
  15. if (callback) callback(this.accept, this.reject);
  16. }
  17.  
  18. accept(value) {
  19. setTimeout(() => {
  20. this.state = FULFILLED;
  21. this.value = value;
  22.  
  23. for (var i = 0; i < this.successCallbacks.length; i++)
  24. this.successCallbacks[i](value);
  25.  
  26. this.successCallbacks = [];
  27. }, 0);
  28. }
  29.  
  30. reject(value) {
  31. setTimeout(() => {
  32. this.state = REJECTED;
  33. this.value = value;
  34.  
  35. if (this.failureCallbacks.length === 0)
  36. throw new Error("Unhandled waiter rejection: " + value);
  37.  
  38. for (var i = 0; i < this.failureCallbacks.length; i++)
  39. this.failureCallbacks[i](value);
  40.  
  41. this.failureCallbacks = [];
  42. });
  43. }
  44.  
  45. then(successCallback, failureCallback) {
  46. var tmpAccept, tmpReject;
  47. var tmpWaiter = new Waiter((accept, reject) => {
  48. tmpAccept = accept;
  49. tmpReject = reject;
  50. });
  51.  
  52. if (successCallback)
  53. this.successCallbacks.push(
  54. this.createRunner(successCallback, tmpAccept, tmpReject)
  55. );
  56.  
  57. if (failureCallback)
  58. this.failureCallbacks.push(
  59. this.createRunner(failureCallback, tmpAccept, tmpReject)
  60. );
  61.  
  62. if (this.state === FULFILLED) this.accept(this.value);
  63. if (this.state === REJECTED) this.reject(this.value);
  64.  
  65. tmpWaiter.resolve = null;
  66. return tmpWaiter;
  67. }
  68.  
  69. catch(failureCallback) {
  70. return this.then(null, failureCallback);
  71. }
  72.  
  73. resolve() {
  74. this.accept();
  75. return this;
  76. }
  77.  
  78. createRunner(callback, tmpAccept, tmpReject) {
  79. return (value) => {
  80. try {
  81. let result = callback(value);
  82.  
  83. if (result && result.isWaiter) {
  84. result.then(tmpAccept, tmpReject);
  85. } else {
  86. tmpAccept(result);
  87. }
  88. } catch (error) {
  89. tmpReject(error);
  90. }
  91. };
  92. }
  93. }
  94.  
  95.  
  96. // Testing Code
  97.  
  98. let testWaiter = new Waiter(function (accept, reject) {
  99. setTimeout(() => accept('hi'), 500);
  100. });
  101.  
  102. testWaiter.then(function (value) {
  103. console.log(value + ' friend');
  104. return new Waiter(function (accept, reject) {
  105. setTimeout(() => reject('oh man'), 1000);
  106. });
  107. })
  108. .then(function (value) {
  109. console.log('todo bien');
  110. },
  111. function (error) {
  112. console.log('"' + error + '"');
  113. });
  114.  
  115. testWaiter.then(function (value) {
  116. console.log(value);
  117. console.log('Robert');
  118. return new Waiter(function (accept, reject) {
  119. setTimeout(() => accept('how?'), 250);
  120. });
  121. })
  122. .then(function (value) {
  123. console.log(value);
  124. })
  125. .then(function (value) {
  126. console.log('what?');
  127. throw new Error('test');
  128. })
  129. .catch(function (value) {
  130. console.log('"' + value + '"');
  131. })
  132. .then(function (value) {
  133. console.log('After error: ' + value);
  134. });
Add Comment
Please, Sign In to add comment