Simple Promise and Then implementation

Here's the shortened code for creating a promise class,

class MyPromise {
  constructor(executor) {
    this.callbacks = [];

    const resolve = res => {
      for (const { callback } of this.callbacks) {
        callback(res);
      }
    };

    executor(resolve);
  }

  then(callback) {
    return new MyPromise((resolve) => {
      const done = res => {
        resolve(callback(res));
      };
      this.callbacks.push({ callback: done });
    });
  }
}


promise = new MyPromise((resolve) => {
  setTimeout(() => resolve(2), 1000);
});

promise.then(result => {
  console.log(result);
  return 2 * result;
}).then(result => console.log(result));


Your question has some issues:

  • The r2 variable is nowhere defined. I will assume result was intended.
  • The setTimeout is doing nothing useful, since you execute result(2) immediately. I will assume setTimeout(() => result(2), 500) was intended.

If the code was really given like that in the interview, then it would be your job to point out these two issues before doing anything else.

One issue with your attempt is that the promise returned by the then method (i.e. result) is never resolved. You need to resolve it as soon as the this promise is resolved, with the value returned by the then callback.

Also, the promise constructor argument is a function that should be executed immediately.

In the following solution, several simplifications are made compared to a correct Promise behaviour.

  • It does not call the then callbacks asynchronously;
  • It does not support multiple then calls on the same promise;
  • It does not provide the rejection path;
  • It does not prevent a promise from resolving twice with a different value;
  • It does not deal with the special case where a then callback returns a promise

console.log("Wait for it...");

class MyPromise {
    constructor(executor) {
        executor(result => this.resolve(result));
    }
    resolve(value) {
        this.value = value;
        this.broadcast();
    }
    then(onFulfilled) {
        const promise = new MyPromise(() => null);
        this.onFulfilled = onFulfilled;
        this.resolver = (result) => promise.resolve(result);
        this.broadcast();
        return promise;
    }
    broadcast() {
        if (this.onFulfilled && "value" in this) this.resolver(this.onFulfilled(this.value)); 
    }
};

// Code provided by interviewer, including two corrections
promise = new MyPromise(
    (result) => {
        setTimeout(()=>result(2), 500); // don't execute result(2) immediately
    });
promise.then(result => {
    console.log(result); // Changed r2 to result.
    return 2 * result;
}).then(result => console.log(result));

Note the 500ms delay in the output, which is what should be expected from the (corrected) setTimeout code.

I posted a full Promises/A+ compliant promise implementation with comments in this answer


How about very simple:

const SimplePromise = function(cb) {
  cb(
    data =>
      (this.data = data) &&
      (this.thenCb || []).forEach(chain => (this.data = chain(this.data))),
    error =>
      (this.error = error) &&
      (this.catchCb || []).forEach(chain => (this.error = chain(this.error)))
  );
  this.then = thenCb =>
    (this.thenCb = [...(this.thenCb || []), thenCb]) && this;
  this.catch = catchCb =>
    (this.catchCb = [...(this.catchCb || []), catchCb]) && this;
};

Example Here: https://codesandbox.io/s/0q1qr8mpxn