Skip to content
Snippets Groups Projects
Select Git revision
  • b87a37f30bc4efc788e88351fe82c712688b3c9e
  • master default protected
  • 1.31
  • 4.24.3
  • 4.24.2
  • 4.24.1
  • 4.24.0
  • 4.23.6
  • 4.23.5
  • 4.23.4
  • 4.23.3
  • 4.23.2
  • 4.23.1
  • 4.23.0
  • 4.22.3
  • 4.22.2
  • 4.22.1
  • 4.22.0
  • 4.21.0
  • 4.20.1
  • 4.20.0
  • 4.19.0
  • 4.18.0
23 results

global.html

Blame
  • processing.js 5.04 KiB
    'use strict';
    
    /**
     * @author schukai GmbH
     */
    
    
    import {internalSymbol} from "../constants.js";
    import {assignToNamespace, Monster} from '../namespace.js';
    import {Base} from "../types/base.js";
    import {getGlobalFunction} from "../types/global.js";
    import {isFunction, isInteger} from "../types/is.js";
    import {Queue} from "../types/queue.js";
    import {validateFunction, validateInteger} from "../types/validate.js";
    
    
    /**
     * @private
     */
    class Callback {
    
        /**
         *
         * @param {function} callback
         * @param {int|undefined} time
         * @throws {TypeError} value is not a function
         * @throws {TypeError} value is not an integer
         * @private
         */
        constructor(callback, time) {
            this[internalSymbol] = {
                callback: validateFunction(callback),
                time: validateInteger(time ?? 0)
            };
        }
    
        /**
         * @private
         * @param  {*} data
         * @return {Promise}
         */
        run(data) {
            const self = this;
            return new Promise((resolve, reject) => {
    
                getGlobalFunction('setTimeout')(() => {
                        try {
                            resolve(self[internalSymbol].callback(data));
                        } catch (e) {
                            reject(e);
                        }
    
                    },
                    self[internalSymbol].time);
    
    
            })
    
        }
    }
    
    /**
     * This class allows to execute several functions in order.
     *
     * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
     * In the example
     *
     * `timeout1, function1, function2, function3, timeout2, function4`
     *
     * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
     *
     * So the execution time is timeout1+timeout1+timeout1+timeout2
     *
     * The result of `run()` is a promise.
     *
     * You can create an instance via the monster namespace `Monster.Util.Processing()`.
     *
     * ```
     * <script type="module">
     * import {Monster} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/monster.js';
     * new Monster.Util.Processing()
     * </script>
     * ```
     *
     * Alternatively, you can also integrate this class individually.
     *
     * ```
     * <script type="module">
     * import {Processing} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/util/processing.js';
     * new Processing();
     * </script>
     * ```
     *
     * @example
     * import {Processing} from 'https://cdn.jsdelivr.net/npm/@schukai/monster@1.30.0/dist/modules/util/processing.js';
     *
     * let startTime = +new Date();
     *
     * new Processing((url)=>{
     *   return fetch(url)
     * },(response)=>{
     *   // do something with the response
     *   console.log(response.status, +new Date()-startTime)
     * },200,()=>{
     *   // this function is called 200 seconds after fetch is received.
     *   console.log('finished', +new Date()-startTime)
     *   return 'done'
     * }).run('https://monsterjs.org/assets/world.json').then(r=>{
     *   console.log(r)
     *   // ↦ "done"
     * })
     *
     * @copyright schukai GmbH
     * @since 1.21.0
     * @memberOf Monster.Util
     * @summary Class to be able to execute function chains
     */
    class Processing extends Base {
    
        /**
         * Create new Processing
         *
         * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
         * In the example
         *
         * `timeout1, function1, function2, function3, timeout2, function4`
         *
         * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
         *
         * So the execution time is timeout1+timeout1+timeout1+timeout2
         *
         * @param {int} timeout Timeout
         * @param {function} callback Callback
         * @throw {TypeError} the arguments must be either integer or functions
         */
        constructor() {
            super();
    
            this[internalSymbol] = {
                queue: new Queue
            };
    
            let time = 0
    
            for (const [, arg] of Object.entries(arguments)) {
                if (isInteger(arg) && arg >= 0) {
                    time = arg;
                } else if (isFunction(arg)) {
                    this[internalSymbol].queue.add(new Callback(arg, time))
                } else {
                    throw new TypeError('the arguments must be either integer or functions')
                }
            }
    
    
        }
    
        /**
         * Adds a function with the desired timeout
         * If no timeout is specified, the timeout of the previous function is used.
         *
         * @param {function} callback
         * @param {int|undefined} time
         * @throws {TypeError} value is not a function
         * @throws {TypeError} value is not an integer
         */
        add(callback, time) {
            this[internalSymbol].queue.add(new Callback(callback, time))
            return this;
        }
    
    
        /**
         * Executes the defined functions in order.
         *
         * @param {*} data
         * @return {Promise}
         */
        run(data) {
            const self = this;
            if (this[internalSymbol].queue.isEmpty()) {
                return Promise.resolve(data);
            }
    
            return this[internalSymbol].queue.poll().run(data).then((result) => {
                return self.run(result);
            });
    
        }
    
    }
    
    assignToNamespace('Monster.Util', Processing);
    export {Monster, Processing}