-1

I have found a custom js promise implementation and trying to understand it but I cant able to figure out how the callbacks are executed or triggered as definition of promise is called immediatly but we are only pushing into the callback array in then implementation

https://playcode.io/364624?tabs=script.js,preview,console

function myPromise(definitionFunction){
  this.thenCallbacks = [];
  this.status = 'pending';
  this.value = undefined;

  definitionFunction(resolver.bind(this),rejector.bind(this));

  function resolver(value)
  {
    this.status = 'resolved';
    this.value = value;
    this.thenCallbacks.forEach(function(func){
      console.log(func);
     this.value =  func(this.value);
    },this);
  }

  function rejector(value)
  {

  }
}

myPromise.prototype.then = function(successCallback,errorCallback){

  this.thenCallbacks.push(successCallback);
  return this;
}


var test = new myPromise(function(resolve,reject){

     var xhttp = new XMLHttpRequest();
     var url = "https://jsonmock.hackerrank.com/api/stocks/search?page="+1;
     xhttp.open("GET",url , true);
     xhttp.onload = function() {
        if (this.readyState == 4 && this.status == 200) {
          resolve(this.responseText);
        }
        else
        {
          reject({
          status: this.status,
          statusText: xhttp.statusText
        })
        }
      };
    xhttp.onerror = function() {
       reject({
        status: this.status,
        statusText: xhr.statusText
      });
    }
    xhttp.send();

  });

  test.then((response)=>'kiran').then((resp)=>{return{name:'kiran'}}).then((resp)=>console.log(resp));

can some one clear this

kiran gudla
  • 177
  • 1
  • 11
  • I don't understand what you're asking, but this promise implementation does not follow the spec because it calls the `.then()` handlers immediately when the promise is resolved rather than on the next tick of the event loop. It also doesn't handle promise chaining (when a `.then()` handler returns another promise). – jfriend00 Jul 12 '19 at 07:03
  • yeah i know this is not perfect implementation according to spec but I want to understand we are only pushing callbacks into the thenarray but how are they executed in time or getting triggered , you can still chain the thens in this implementaion please check the playcode link – kiran gudla Jul 12 '19 at 07:10
  • All `.then()` is supposed to do is to register callbacks that can be called later (when the promise is resolved or rejected). Still don't understand what you're asking. "Register" in this case means to push them into an array to save them for later use. – jfriend00 Jul 12 '19 at 07:11
  • Plenty of other issues with this implementation too as it doesn't call a `.then()` handler when it's added after the promise is already resolved either. – jfriend00 Jul 12 '19 at 07:16
  • I'm not talking about chaining `.then().then()`. I'm talking about return a new promise from a `.then()` handler which is supposed to insert that new promise into the chain which this doesn't do. Basically, this is about a 20% implementation. – jfriend00 Jul 12 '19 at 07:17
  • yeah its 20% only , but what I didnt understand is how callbacks are executed as and when they are pushed into thenArray as the resolver function is called on success of http call and then how could the latest callbacks are triggered as and when they are pushed into array – kiran gudla Jul 12 '19 at 07:32
  • Can't answer any more questions here as this implementation is just pure junk. So many things it does wrong, no point in discussing it works. Here's another thing wrong, `.then()` is supposed to return a NEW promise, not the same promise. Bye. – jfriend00 Jul 12 '19 at 07:35
  • can you please point me to the right implementation as I find lot of implementatios – kiran gudla Jul 12 '19 at 08:44
  • You can start here: https://www.promisejs.org/implementing/ – jfriend00 Jul 12 '19 at 16:05
  • `this.value = func(this.value);` or `return this;` in `then()` - um, that's not how promises work. Not at all. – Bergi Jul 12 '19 at 21:41

1 Answers1

1

First off, this is a particularly poor implementation of a promise as it does all sorts of things wrong:

  1. It doesn't resolve asynchronously after the current thread of execution has finished which can cause inconsistent timing issues.
  2. It doesn't support proper chaining with .then().then() where .then() returns a new promise so the 2nd .then() calls it's handlers only after the first promise is resolved.
  3. It doesn't support proper chaining where a .then() callback handler can return a promise that will be inserted into the chain
  4. It doesn't call .then() handlers that are added after the promise has already been resolved.
  5. It doesn't latch the state of the promise so it can't be changed.
  6. It doesn't catch synchronous exceptions in the executor or .then() or .catch() handlers and turn them into rejected promises.

For a much better implementation, I'd suggest you consult this code: https://www.promisejs.org/implementing/ which apparent started as this stackoverflow answer as that will give you a much better idea of what is involved in implementing promises.

I cant able to figure out how the callbacks are executed or triggered as definition of promise is called immediately but we are only pushing into the callback array in then implementation

What .then() does is register a callback (save it) so that it can be called at some future time. So, it is natural that it would just add a callback to an array and then the callbacks in that array can be executed at some future time (like when the promise becomes fulfilled).

In this implementation definitionFunction() is the promise executor. It's the callback that is passed to the new Promise(fn) constructor and it is supposed to be called immediately.

.then() callbacks are then stored in an array.

Then, sometime later when the resolver() function from the executor is called, it will iterate that array with this.thenCallbacks.forEach() and call each function in the array.

But, this implementation doesn't work properly in a number of ways in doing this. If resolver() is called immediately, then the .thenCallbacks array will be empty because .then() hasn't yet been called on the promise and then when .then() is called sometime later on the already resolved promise, it doesn't ever call the callback.

As I've said in the comments, I don't wish to spend any more time discussing how such a flawed promise implementation works. I tried to answer your direct question and steer you towards a much better, more accurate and more complete promise implementation that you can study going forward. This one has all sorts of problems so, in my judgment, it's not worth spending more time understand how it works.

You can also spend some time reading the Promises/A+ specification which really isn't all that complicated to read or understand.

jfriend00
  • 683,504
  • 96
  • 985
  • 979