Source: Promise.js

(function() {
    /**
     * use native implementation if available
     * in some older UI5 systems is a Promise implementation for IE that is incomplete
     * therefore check the whole interface before using it; otherwise use our solution
     * @return {Promise|undefined}
     */
    if ((() => {
        const {Promise} = window;
        if (typeof Promise?.all === 'function' &&
            typeof Promise?.resolve === 'function' &&
            typeof Promise?.reject === 'function' &&
            typeof Promise?.prototype?.then === 'function' &&
            typeof Promise?.prototype?.catch === 'function' &&
            typeof Promise?.prototype?.finally === 'function')  // XRAY-2865
        {
            return Help4.Promise = Promise;
        }
    })()) return;

    const setImmediate = window.setImmediate || (executor => void window.setTimeout(executor, 0));

    /**
     * @typedef {Object} Help4.Promise.Callback
     * @property {Function|null} onResolve
     * @property {Function|null} onReject
     * @property {Help4.Promise} promise
     */

    /**
     * @typedef {Function} Help4.Promise.Executor
     * @param {Function} resolve
     * @param {Function} reject
     */

    /**
     * @typedef {{pending: 'pending', fulfilled: 'fulfilled', promise: 'promise', error: 'error'}} Help4.Promise.STATE
     */
    const STATE = {
        pending: 'pending',
        fulfilled: 'fulfilled',
        error: 'error',
        promise: 'promise'
    };

    /** @augments Promise */
    Help4.Promise = class {
        /**
         * @param {Help4.Promise.Executor} executor
         */
        constructor(executor) {
            this._state = STATE.pending;
            this._value = undefined;
            this._callbacks = [];
            _execute.call(this, executor);
        }

        /**
         * @param {*} [value = undefined]
         * @return {Help4.Promise<*>}
         */
        static resolve(value = undefined) {
            const {Promise} = Help4;
            return value instanceof Promise ? value : new Promise(resolve => void resolve(value));
        }

        /**
         * @param {*} [reason = undefined]
         * @return {Help4.Promise<*>}
         */
        static reject(reason = undefined) {
            return new Help4.Promise((resolve, reject) => void reject(reason));
        }

        /**
         * @param {Array<Help4.Promise<*>>} promises
         * @return {Help4.Promise<*>}
         */
        static all(promises) {
            return new Help4.Promise((resolve, reject) => {
                let count = promises.length;
                const results = new Array(count);
                if (!count) return resolve(results);

                const execute = (idx, promise) => {
                    try {
                        promise
                        .then(value => {
                            results[idx] = value;
                            !(--count) && resolve(results);
                        })
                        .catch(reject);
                    } catch (e) {
                        reject(e);
                    }
                }

                for (const [i, promise] of Help4.arrayEntries(promises)) {
                    if (promise instanceof Help4.Promise) {
                        execute(i, promise);
                    } else {
                        results[i] = promise;
                        !(--count) && resolve(results);
                    }
                }
            });
        }

        /**
         * @member
         */
        destroy() {
            delete this._state;
            delete this._value;
            delete this._callbacks;
        }

        /**
         * @param {Function} onResolve
         * @param {Function} [onReject]
         * @return {Help4.Promise<*>}
         */
        then(onResolve, onReject = null) {
            const promise = new Help4.Promise(() => {});

            _callback.call(this, {
                onResolve: onResolve || null,
                onReject: onReject || null,
                promise
            });

            return promise;
        }

        /**
         * @param {Function} onReject
         * @return {Help4.Promise<*>}
         */
        catch(onReject) {
            return this.then(null, onReject);
        }

        /**
         * @param {Function} onFinally
         * @return {Help4.Promise<*>}
         */
        finally(onFinally) {
            const onResolve = value => {
                return Help4.Promise.resolve(onFinally())
                .then(() => value);
            }

            const onReject = reason => {
                return Help4.Promise.resolve(onFinally())
                .then(() => Help4.Promise.reject(reason));
            }

            return this.then(onResolve, onReject);
        }
    }

    /**
     * @param {Help4.Promise.Executor} executor
     * @memberof Help4.Promise#
     * @private
     */
    function _execute(executor) {
        let done = false;
        const onResolve = value => void (!done && (done = true) && _resolve.call(this, value));
        const onReject = reason => void (!done && (done = true) && _reject.call(this, reason));

        try {
            executor(onResolve, onReject);
        } catch(e) {
            onReject(e);
        }
    }

    /**
     * @param {*} value
     * @memberof Help4.Promise#
     * @private
     */
    function _resolve(value) {
        try {
            _setValue.call(this, value instanceof Help4.Promise ? STATE.promise : STATE.fulfilled, value);
        } catch(e) {
            _reject.call(this, e);
        }
    }

    /**
     * @param {*} reason
     * @memberof Help4.Promise#
     * @private
     */
    function _reject(reason) {
        _setValue.call(this, STATE.error, reason);
    }

    /**
     * @param {Help4.Promise.STATE} state
     * @param {*} value
     * @memberof Help4.Promise#
     * @private
     */
    function _setValue(state, value) {
        this._state = state;
        this._value = value;

        /** @type {Help4.Promise.Callback} */
        let c;
        while (c = this._callbacks.shift()) {
            _callback.call(this, c);
        }
        this._callbacks = null;
    }

    /**
     *
     * @param {Help4.Promise.Callback} callback
     * @memberof Help4.Promise#
     * @private
     */
    function _callback(callback) {
        let scope = this;
        while (scope._state === STATE.promise) scope = scope._value;

        if (scope._state === STATE.pending) {
            scope._callbacks.push(callback);
        } else {
            setImmediate(() => _forwardExecute.call(scope, callback));
        }
    }

    /**
     * @param {Help4.Promise.Callback} callback
     * @memberof Help4.Promise#
     * @private
     */
    function _forwardExecute(callback) {
        const fun = this._state === STATE.fulfilled ? callback.onResolve : callback.onReject;

        if (fun) {
            let result;
            try {
                result = fun(this._value);
            } catch(e) {
                _reject.call(callback.promise, e);
                return;
            }
            _resolve.call(callback.promise, result);
        } else {
            this._state === STATE.fulfilled
                ? _resolve.call(callback.promise, this._value)
                : _reject.call(callback.promise, this._value);
        }
    }
})();