JSFiddle - React, Tailwind, and code Playground

by Sahil Batla

JavaScript

/* Singleton Pattern, only one executor, therefore calling twice should raise an error */

var syncFuncs = {
  collection: [],
  currentMethodIndex: 0,
  callback: null,
  maxDelay: 10000,
  callbackCalled: false,
  currentlyExecuting: false,
    
  register: function(func) {
    this.collection.push(func);
  },
    
  //sets executing true(returns error if called again) and calls   method synchornously
  start: function() {
    if (!this.currentlyExecuting) {
      this.currentlyExecuting = true;
      this.currentMethodIndex = 0;
      this.setCallback();
      this.executeCurrentMethod();
    } else {
      alert('Currently executing, wait till it finishes');
    }
  },
    
  //setCallback in end of all methods and on a timer with maxDelay  
  setCallback: function() {
    this.collection.push(this.callback);
    setTimeout(this.callback, this.maxDelay);
  },
    
  executeCurrentMethod: function() {
    this.collection[this.currentMethodIndex]();  
  },
    
  //Add callback, only 1 callback allowed, so if you try to add more that will be over-riden(Assumption)
  addCallback: function(callback, delay) {
    this.callback = function() {
      if (!syncFuncs.callbackCalled) {
        callback();
        syncFuncs.callbackCalled = true;
      }
    }
    this.maxDelay = delay;
  },
    
  //mark current method done and move to next one
  markDone: function() {
    if (this.currentMethodIndex < this.collection.length - 1) {
      this.currentMethodIndex++;
      this.executeCurrentMethod();
    }
  }
}

syncFuncs.register(function() {
  var x = function() { alert(1); syncFuncs.markDone(); }
  //change to more than 3000 to see promise run first
  window.setTimeout(x, 2000);
});
syncFuncs.register(function(){alert(2); syncFuncs.markDone();})
syncFuncs.addCallback(function(){alert(3)}, 3000);

syncFuncs.start();