UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

164 lines (163 loc) 5.38 kB
/** * DevExtreme (esm/core/utils/deferred.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { isDeferred, isDefined, isPromise } from "../utils/type"; import { extend } from "../utils/extend"; import Callbacks from "../utils/callbacks"; var deferredConfig = [{ method: "resolve", handler: "done", state: "resolved" }, { method: "reject", handler: "fail", state: "rejected" }, { method: "notify", handler: "progress" }]; var _DeferredObj = function() { var that = this; this._state = "pending"; this._promise = {}; deferredConfig.forEach(function(config) { var methodName = config.method; this[methodName + "Callbacks"] = new Callbacks; this[methodName] = function() { return this[methodName + "With"](this._promise, arguments) }.bind(this); this._promise[config.handler] = function(handler) { if (!handler) { return this } var callbacks = that[methodName + "Callbacks"]; if (callbacks.fired()) { handler.apply(that[methodName + "Context"], that[methodName + "Args"]) } else { callbacks.add(function(context, args) { handler.apply(context, args) }.bind(this)) } return this } }.bind(this)); this._promise.always = function(handler) { return this.done(handler).fail(handler) }; this._promise.catch = function(handler) { return this.then(null, handler) }; this._promise.then = function(resolve, reject) { var result = new _DeferredObj; ["done", "fail"].forEach(function(method) { var callback = "done" === method ? resolve : reject; this[method]((function() { if (!callback) { result["done" === method ? "resolve" : "reject"].apply(this, arguments); return } var callbackResult = callback && callback.apply(this, arguments); if (isDeferred(callbackResult)) { callbackResult.done(result.resolve).fail(result.reject) } else if (isPromise(callbackResult)) { callbackResult.then(result.resolve, result.reject) } else { result.resolve.apply(this, isDefined(callbackResult) ? [callbackResult] : arguments) } })) }.bind(this)); return result.promise() }; this._promise.state = function() { return that._state }; this._promise.promise = function(args) { return args ? extend(args, that._promise) : that._promise }; this._promise.promise(this) }; deferredConfig.forEach((function(config) { var methodName = config.method; var state = config.state; _DeferredObj.prototype[methodName + "With"] = function(context, args) { var callbacks = this[methodName + "Callbacks"]; if ("pending" === this.state()) { this[methodName + "Args"] = args; this[methodName + "Context"] = context; if (state) { this._state = state } callbacks.fire(context, args) } return this } })); export function fromPromise(promise, context) { if (isDeferred(promise)) { return promise } else if (isPromise(promise)) { var d = new _DeferredObj; promise.then((function() { d.resolveWith.apply(d, [context].concat([ [].slice.call(arguments) ])) }), (function() { d.rejectWith.apply(d, [context].concat([ [].slice.call(arguments) ])) })); return d } return (new _DeferredObj).resolveWith(context, [promise]) } var whenFunc = function() { if (1 === arguments.length) { return fromPromise(arguments[0]) } var values = [].slice.call(arguments); var contexts = []; var resolvedCount = 0; var deferred = new _DeferredObj; var updateState = function(i) { return function(value) { contexts[i] = this; values[i] = arguments.length > 1 ? [].slice.call(arguments) : value; resolvedCount++; if (resolvedCount === values.length) { deferred.resolveWith(contexts, values) } } }; for (var i = 0; i < values.length; i++) { if (isDeferred(values[i])) { values[i].promise().done(updateState(i)).fail(deferred.reject) } else { resolvedCount++ } } if (resolvedCount === values.length) { deferred.resolveWith(contexts, values) } return deferred.promise() }; export function setStrategy(value) { _DeferredObj = value.Deferred; whenFunc = value.when } export function Deferred() { return new _DeferredObj } export function when() { return whenFunc.apply(this, arguments) }