JSFiddle - React, Tailwind, and code Playground

by Eduard Dyckman

HTML

<button id="action">
  ACTION
</button>
<button id="fail">
FAIL
</button>
<div id="result">

</div>

JavaScript

class EdsPromise {
  constructor(executor) {
    this._runQueue = [];
    this.status = EdsPromise.PENDING;
    this._fulfillValue = undefined;
    executor(this._resolve.bind(this), this._reject.bind(this));
  }

  then(resolveCb, rejectCb) {
    const resultPromise = new EdsPromise((resolve, reject) => {
      this._runQueue.push({
        resolve(value) {
          const result = resolveCb(value);
          if (EdsPromise.isPromise(result)) {
            result.then(resolve, reject);
          } else {
            resolve(result);
          }
        },
        reject(value) {
          if (rejectCb) {
            const result = rejectCb(value);
            if (EdsPromise.isPromise(result)) {
              result.then(resolve, reject);
            } else {
              reject(result);
            }
          }
        }
      })
    });
    this._fulfill();
    return resultPromise;
  }

  _resolve(value) {
    this.status = EdsPromise.RESOLVED;
    this._fulfillValue = value;
    this._fulfill();
  }

  _reject(value) {
    this.status = EdsPromise.REJECTED;
    this._fulfillValue = value;
    this._fulfill();
  }
  _fulfill() {
    while (this.status !== EdsPromise.PENDING && this._runQueue.length) {
      const {
        resolve,
        reject
      } = this._runQueue.shift();
      if (this.status === EdsPromise.RESOLVED) {
        resolve(this._fulfillValue);
      }
      if (this.status === EdsPromise.REJECTED) {
        reject(this._fulfillValue);
      }
    }
  }
}
EdsPromise.__isPromise = Symbol('EdsPromise');
EdsPromise.isPromise = (promise) => promise && promise.constructor.__isPromise === EdsPromise.__isPromise;
EdsPromise.PENDING = Symbol('pending');
EdsPromise.RESOLVED = Symbol('resolved');
EdsPromise.REJECTED = Symbol('rejected');

action.addEventListener('click', () => {
  const p = new EdsPromise((resolve) => {
    resolve('After resolve add some text');
  })
  p.then((text) => {
    result.innerHTML += text + '<br>';
    return new...