0

I have been trying to understand the architecture behind a promise call in javscript and here is something that i assumed is happening behind the scene

function Promise() {

  this.stack = [];

  this.then = function(fn) {
    this.stack.push(fn);
    return this;
  }

  this.resolve = function(data) {

    if (this.stack.length) {
      var cb = this.stack[0];

      this.stack.shift();
      cb.call(null, {
        resolve: this.resolve.bind(this)
      }, data);
    }

  }
}


// --- below is a working implementation --- //

var bar = function() {
  var promise = new Promise();
  setTimeout(function() {
    console.log("1");
    promise.resolve();
  }, 2000);
  return promise;
}

bar().then(function(p) {
  setTimeout(function() {
    console.log("2");
    p.resolve();
  }, 1000);
}).then(function(p) {
  setTimeout(function() {
    console.log("3");
    p.resolve();
  }, 500);
}).then(function(p) {
  setTimeout(function() {
    console.log("4");
    p.resolve();
  }, 300);
});

in my library, after every resolve call, i am calling the next callback in the stack and shifting the array by one

however in other libraries that i have linked, every-time the first promise is resolved a loop is being run through out the entire array while it keeps calling the callback stacks.

D.js

function execCallbacks() {
  /*jshint bitwise:false*/
  if (status === 0) {
    return;
  }
  var cbs = pendings,
    i = 0,
    l = cbs.length,
    cbIndex = ~status ? 0 : 1,
    cb;
  pendings = [];
  for (; i < l; i++) {
    (cb = cbs[i][cbIndex]) && cb(value);
  }
}

tiny Promise.js

_complete: function(which, arg) {
  // switch over to sync then()
  this.then = which === 'resolve' ?
    function(resolve, reject) {
      resolve && resolve(arg);
    } :
    function(resolve, reject) {
      reject && reject(arg);
    };
  // disallow multiple calls to resolve or reject
  this.resolve = this.reject =
    function() {
      throw new Error('Promise already completed.');
    };
  // complete all waiting (async) then()s
  var aThen, i = 0;
  while (aThen = this._thens[i++]) {
    aThen[which] && aThen[which](arg);
  }
  delete this._thens;
}

tiny closure Promise.js

function complete(type, result) {
  promise.then = type === 'reject' ?
    function(resolve, reject) {
      reject(result);
    } :
    function(resolve) {
      resolve(result);
    };

  promise.resolve = promise.reject = function() {
    throw new Error("Promise already completed");
  };

  var i = 0,
    cb;
  while (cb = callbacks[i++]) {
    cb[type] && cb[type](result);
  }

  callbacks = null;
}

I want to understand, why is there a loop being run through the array to handle the next function chained to the resolve ! what am i missing in my architecture?

isnvi23h4
  • 1,910
  • 1
  • 27
  • 45
  • Because your `then` method is broken. It should return a *new* promise, not the old one. A single promise object does not store a "chain" of callbacks. – Bergi Nov 17 '18 at 17:17
  • 3
    I recommend to have a look at [this sample implementation](https://stackoverflow.com/a/15668353/1048572), which doesn't have error handling (rejections) but otherwise all important architectural concepts – Bergi Nov 17 '18 at 17:18
  • To add to what @Bergi says, imagine you have `prom.then(c1).then(c2); prom.then(c3);` c1 and c3 are pushed un prom's internal array (and can be run sequentially), whereas c2 will be pushed in the internal array of the new promise returned by `prom.then` – Joel Nov 17 '18 at 19:44
  • @Bergi no that not how it would work, jsfiddle example jsfiddle.net/o45as9gm – isnvi23h4 Nov 17 '18 at 21:02
  • @souparnomajumder That's how promises *do* work. Your `Foo` works differently. – Bergi Nov 17 '18 at 21:03
  • @Bergi i have implemented a working code in the question – isnvi23h4 Nov 18 '18 at 10:54
  • @Joel i have implemented a working code in the question – isnvi23h4 Nov 18 '18 at 10:54
  • @souparnomajumder Yes, that's working, but not a promise :-) – Bergi Nov 18 '18 at 11:02

1 Answers1

1

in my library, after every resolve call, i am calling the next callback in the stack and shifting the array by one

That's a callback queue, not a promise. A promise can be resolved only once. When making a .then() chain of promises, it simply creates multiple promise objects, each one representing the asynchronous result after a step.

You might want to have a look at the core features of promises.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375