JSFiddle - React, Tailwind, and code Playground

by joplomacedo

JavaScript

class Subject {
	constructor( initialVal ) {
  	this.val = 0;
    this.subscribers = [];
  }
  
  subscribe( cb ) {
    this.subscribers.push(cb)
  }
  
  next( val ) {
  	this.val = val;
    this.subscribers.forEach( subscriber => subscriber(val) );
  }
  
  getValue() {
	  return this.val;
  }
}


const makeReqAware = ( () => { //IIF
    const ibMaxConcurrentReqs = 50;
    let ibConcurrentReqs$ = new Subject(0);

    function incIbReqsRunningCount() {
        const ibConcurrentReqs = ibConcurrentReqs$.getValue();
        ibConcurrentReqs$.next(ibConcurrentReqs+1);
    }

    function decIbReqsRunningCount() {
        const ibConcurrentReqs = ibConcurrentReqs$.getValue();
        ibConcurrentReqs$.next(ibConcurrentReqs-1);

    }

    const queue = [];

    ibConcurrentReqs$.subscribe( ibConcurrentReqs => {
        if ( ibConcurrentReqs < ibMaxConcurrentReqs ) {
            if ( queue.length ) {
                const {fn, resolver} = queue.shift();

                fn().then( (...args) => {
                    resolver.resolve(...args)
                }).catch( (...args) => {
                    resolver.reject(...args)
                })
            }
        }
    })

    return ibFn => {

        function _ibFn( ...args ) {
            incIbReqsRunningCount();

            return ibFn(...args).then( (...args) => {
                decIbReqsRunningCount();
                return Promise.resolve(...args);
            }).catch( (...args) => {
                decIbReqsRunningCount();
                return Promise.reject(...args);
            })
        }

        return ( ...args ) => {
            const ibConcurrentReqs = ibConcurrentReqs$.getValue();

            if ( ibConcurrentReqs + 1 <= ibMaxConcurrentReqs ) {
                return _ibFn(...args);

            } else {
                const resolver = createResolver();

                queue.push({
                    fn: () => _ibFn(...args),
                    resolver
                })

             ...