deferred.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * DevExtreme (core/utils/deferred.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var typeUtils = require("../utils/type");
  11. var isPromise = typeUtils.isPromise;
  12. var isDeferred = typeUtils.isDeferred;
  13. var extend = require("../utils/extend").extend;
  14. var Callbacks = require("../utils/callbacks");
  15. var deferredConfig = [{
  16. method: "resolve",
  17. handler: "done",
  18. state: "resolved"
  19. }, {
  20. method: "reject",
  21. handler: "fail",
  22. state: "rejected"
  23. }, {
  24. method: "notify",
  25. handler: "progress"
  26. }];
  27. var _Deferred = function() {
  28. var that = this;
  29. this._state = "pending";
  30. this._promise = {};
  31. deferredConfig.forEach(function(config) {
  32. var methodName = config.method;
  33. this[methodName + "Callbacks"] = new Callbacks;
  34. this[methodName] = function() {
  35. return this[methodName + "With"](this._promise, arguments)
  36. }.bind(this);
  37. this._promise[config.handler] = function(handler) {
  38. if (!handler) {
  39. return this
  40. }
  41. var callbacks = that[methodName + "Callbacks"];
  42. if (callbacks.fired()) {
  43. handler.apply(that[methodName + "Context"], that[methodName + "Args"])
  44. } else {
  45. callbacks.add(function(context, args) {
  46. handler.apply(context, args)
  47. }.bind(this))
  48. }
  49. return this
  50. }
  51. }.bind(this));
  52. this._promise.always = function(handler) {
  53. return this.done(handler).fail(handler)
  54. };
  55. this._promise.catch = function(handler) {
  56. return this.then(null, handler)
  57. };
  58. this._promise.then = function(resolve, reject) {
  59. var result = new _Deferred;
  60. ["done", "fail"].forEach(function(method) {
  61. var callback = "done" === method ? resolve : reject;
  62. this[method](function() {
  63. if (!callback) {
  64. result["done" === method ? "resolve" : "reject"].apply(this, arguments);
  65. return
  66. }
  67. var callbackResult = callback && callback.apply(this, arguments);
  68. if (isDeferred(callbackResult)) {
  69. callbackResult.done(result.resolve).fail(result.reject)
  70. } else {
  71. if (isPromise(callbackResult)) {
  72. callbackResult.then(result.resolve, result.reject)
  73. } else {
  74. result.resolve.apply(this, typeUtils.isDefined(callbackResult) ? [callbackResult] : arguments)
  75. }
  76. }
  77. })
  78. }.bind(this));
  79. return result.promise()
  80. };
  81. this._promise.state = function() {
  82. return that._state
  83. };
  84. this._promise.promise = function(args) {
  85. return args ? extend(args, that._promise) : that._promise
  86. };
  87. this._promise.promise(this)
  88. };
  89. deferredConfig.forEach(function(config) {
  90. var methodName = config.method;
  91. var state = config.state;
  92. _Deferred.prototype[methodName + "With"] = function(context, args) {
  93. var callbacks = this[methodName + "Callbacks"];
  94. if ("pending" === this.state()) {
  95. this[methodName + "Args"] = args;
  96. this[methodName + "Context"] = context;
  97. if (state) {
  98. this._state = state
  99. }
  100. callbacks.fire(context, args)
  101. }
  102. return this
  103. }
  104. });
  105. exports.fromPromise = function(promise, context) {
  106. if (isDeferred(promise)) {
  107. return promise
  108. } else {
  109. if (isPromise(promise)) {
  110. var d = new _Deferred;
  111. promise.then(function() {
  112. d.resolveWith.apply(d, [context].concat([
  113. [].slice.call(arguments)
  114. ]))
  115. }, function() {
  116. d.rejectWith.apply(d, [context].concat([
  117. [].slice.call(arguments)
  118. ]))
  119. });
  120. return d
  121. }
  122. }
  123. return (new _Deferred).resolveWith(context, [promise])
  124. };
  125. var when = function() {
  126. if (1 === arguments.length) {
  127. return exports.fromPromise(arguments[0])
  128. }
  129. var values = [].slice.call(arguments);
  130. var contexts = [];
  131. var resolvedCount = 0;
  132. var deferred = new _Deferred;
  133. var updateState = function(i) {
  134. return function(value) {
  135. contexts[i] = this;
  136. values[i] = arguments.length > 1 ? [].slice.call(arguments) : value;
  137. resolvedCount++;
  138. if (resolvedCount === values.length) {
  139. deferred.resolveWith(contexts, values)
  140. }
  141. }
  142. };
  143. for (var i = 0; i < values.length; i++) {
  144. if (isDeferred(values[i])) {
  145. values[i].promise().done(updateState(i)).fail(deferred.reject)
  146. } else {
  147. resolvedCount++
  148. }
  149. }
  150. if (resolvedCount === values.length) {
  151. deferred.resolveWith(contexts, values)
  152. }
  153. return deferred.promise()
  154. };
  155. exports.setStrategy = function(value) {
  156. _Deferred = value.Deferred;
  157. when = value.when
  158. };
  159. exports.Deferred = function() {
  160. return new _Deferred
  161. };
  162. exports.when = function() {
  163. return when.apply(this, arguments)
  164. };