finally.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. "use strict";
  2. module.exports = function(Promise, NEXT_FILTER, tryConvertToPromise) {
  3. var util = require("./util.js");
  4. var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver;
  5. var isPrimitive = util.isPrimitive;
  6. var thrower = util.thrower;
  7. function returnThis() {
  8. return this;
  9. }
  10. function throwThis() {
  11. throw this;
  12. }
  13. function return$(r) {
  14. return function() {
  15. return r;
  16. };
  17. }
  18. function throw$(r) {
  19. return function() {
  20. throw r;
  21. };
  22. }
  23. function promisedFinally(ret, reasonOrValue, isFulfilled) {
  24. var then;
  25. if (wrapsPrimitiveReceiver && isPrimitive(reasonOrValue)) {
  26. then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue);
  27. } else {
  28. then = isFulfilled ? returnThis : throwThis;
  29. }
  30. return ret._then(then, thrower, undefined, reasonOrValue, undefined);
  31. }
  32. function finallyHandler(reasonOrValue) {
  33. var promise = this.promise;
  34. var handler = this.handler;
  35. var ret = promise._isBound()
  36. ? handler.call(promise._boundTo)
  37. : handler();
  38. if (ret !== undefined) {
  39. var maybePromise = tryConvertToPromise(ret, promise);
  40. if (maybePromise instanceof Promise) {
  41. maybePromise = maybePromise._target();
  42. return promisedFinally(maybePromise, reasonOrValue,
  43. promise.isFulfilled());
  44. }
  45. }
  46. if (promise.isRejected()) {
  47. NEXT_FILTER.e = reasonOrValue;
  48. return NEXT_FILTER;
  49. } else {
  50. return reasonOrValue;
  51. }
  52. }
  53. function tapHandler(value) {
  54. var promise = this.promise;
  55. var handler = this.handler;
  56. var ret = promise._isBound()
  57. ? handler.call(promise._boundTo, value)
  58. : handler(value);
  59. if (ret !== undefined) {
  60. var maybePromise = tryConvertToPromise(ret, promise);
  61. if (maybePromise instanceof Promise) {
  62. maybePromise = maybePromise._target();
  63. return promisedFinally(maybePromise, value, true);
  64. }
  65. }
  66. return value;
  67. }
  68. Promise.prototype._passThroughHandler = function (handler, isFinally) {
  69. if (typeof handler !== "function") return this.then();
  70. var promiseAndHandler = {
  71. promise: this,
  72. handler: handler
  73. };
  74. return this._then(
  75. isFinally ? finallyHandler : tapHandler,
  76. isFinally ? finallyHandler : undefined, undefined,
  77. promiseAndHandler, undefined);
  78. };
  79. Promise.prototype.lastly =
  80. Promise.prototype["finally"] = function (handler) {
  81. return this._passThroughHandler(handler, true);
  82. };
  83. Promise.prototype.tap = function (handler) {
  84. return this._passThroughHandler(handler, false);
  85. };
  86. };