Search code examples
javascriptecmascript-6promisees6-promise

About chaining es6 Promises, then() and value consumption


This is tightly coupled to Chaining .then() calls in ES6 promises ...

I tried this with some functions that make up a chain of promises, so basically:

var PromiseGeneratingMethod = function(){
  return p = new Promise((resolve, reject) =>{
    resolve(1)
  });
}

var inBetweenMethod = function(){
  return PromiseGeneratingMethod()
    .then((resolved) => {
    if(resolved){
      console.log('resolved in between');
      //return resolved
        /* this changes output to
        resolved in between
        resolved at last*/
    }else{
      console.log('something went terribly wrong in betweeen', resolved);
    }
  });
}

inBetweenMethod().then((resolved) =>{
  if(resolved){
    console.log('resolved at last')
  }else{
    console.log('something went terribly wrong', resolved);
  }
})

/* ouput: 
resolved in between
something went terribly wrong undefined*/

I don't understand why it is like that. doesn't have a Promise just ONE associated return value? why can I change that value in every then? It seems irrational to me. A Promise Object can only have one return value and I thought every then handler will receive the same parameter after the Promise gets resolved?

This way, having two Methods which call then() on the same Promise, the latter one (in asynchronous environments you never know what that is...) will ALWAYS get an empty result, except if EVERY then returns the desired value

If I got it right, the only good thing is that you can build a then().then().then() chain to make it almost synchronous (by returning arbitrary values in every then()) but you still could achieve the same with nested Promises, right?

Can someone help me understand why es6 Promises work that way and if there are more caveats to using those?


Solution

  • doesn't have a promise just ONE associated return value?

    Yes.

    why can I change that value in every then?

    Because every .then() call does return a new promise.

    having two methods which call then() on the same Promise

    That's not what you're doing. Your then callbacks are installed on different promises, that's why they get different values.

    You could do

    function inBetweenMethod() {
      var promise = PromiseGeneratingMethod();
      promise.then(resolved => { … }); // return value is ignored
      return promise;
    }
    

    but you should really avoid that. You already noticed that you can get the expected behaviour with

    function inBetweenMethod() {
      var promise = PromiseGeneratingMethod();
      var newPromise = promise.then(value => {
         …
         return value;
      });
      return newPromise;
    }
    

    where the newPromise is resolved with the value that is returned by the callback - possibly the same value that promise fulfilled with.