JSFiddle - React, Tailwind, and code Playground

by joplomacedo

JavaScript

const attemptQueue = {
  _queue: [],


  add(id, cb) {
    //cancel existing if it exists
    this.cancel(id);

    this._queue.push({
      id,
      cb,
      isExecuting: false
    });

    this.execute(id);
  },

  cancel(id) {
    const idxOfId = this._queue.findIndex(item => item.id === id);

    if (idxOfId > -1) {
      this._queue.splice(idxOfId, 1)
    }
  },

  cancelAll() {
    this._queue = [];
  },

  execute(id) {
    const item = this._queue.find(item => item.id === id);

    if (item) {

      return item.cb()
        .then(() => {
          this.cancel(id);
        }).catch(err => {
          // keep in queue
        })
    }
  },

  executeAll() {
    return Promise.all(
      this._queue.map(item => this.execute(item.id))
    );
  }
}


let i = 0;
let j = 0;
attemptQueue.add('alertIt', () => {
  ++i;

  return new Promise((resolve, reject) => {
    i < 5 ? reject() : resolve();
  }).then(() => {

    document.body.innerHTML = 'it ' + j;
    j++;
  });

})

attemptQueue.executeAll();
attemptQueue.cancel('alertIt');
attemptQueue.executeAll();
attemptQueue.executeAll();
attemptQueue.executeAll();
attemptQueue.executeAll();
attemptQueue.executeAll();
attemptQueue.executeAll();
attemptQueue.executeAll();

setTimeout(() => {
  attemptQueue.executeAll();
  attemptQueue.executeAll();
})