1

To cement my understanding of JavaScript's Promise API, I have been working through this excellent example of an implementation in JavaScript, which is based off this Stackoverflow answer.

However, I found in its full form (see website), it was difficult to wrap my head around all the callbacks and wrapped values. So, I reduced it down to functionality that doesn't work with .catch() and doesn't guarantee a resolver function (function passed into new Promise(this_function_here)) won't invoke resolve() more than once. Below:

const PENDING = 0;
const FULFILLED = 1;
const REJECTED = 2;

function MyPromise(executor) {
    let state = PENDING;
    let value = null;
    let handlers = [];

    function fulfill(result) {
        state = FULFILLED;
        // In the promise website, this result would have been checked]
        // before right now to see if it has a .then property, why? 
        value = result;
        handlers.forEach(handle);
        handlers = null;
    }

    function handle(handler) {
        if (state === PENDING) {
            handlers.push(handler);
        } else {
            if (state === FULFILLED && typeof handler.onFulfilled === 'function') {
                handler.onFulfilled(value);
            }
        }
    }

    this.then = function (onFulfilled) {
        return new MyPromise(function (resolve) {
            setTimeout(function () {
                handle({
                    onFulfilled: function (result) {
                        return resolve(onFulfilled(result));
                    }
                })
            }, 0)
        });
    }

    executor(fulfill);

}

And example to demonstrate the functionality I'm interested in for now, until I can better grasp error handling:

function fetch_and_callback(resolve) {
    setTimeout(() => {
        resolve('hello')
    }, 1000)
};
const do_async = new MyPromise(fetch_and_callback);

function printer(value) {
    console.log('printer coming');
    console.log(value);
}
function modifier(result) {
    return result + 'has been modified'
}
do_async.then(modifier).then(printer);

I am rebuilding my basic example up to be equivalent to the given example on the promisejs website, however I can't figure out the point of the getThen function. It takes a wrapped "result" (a resolved value) and checks to see if it has a .then property. What use case does this guarantee? The function looks like this:

function getThen(value) {
  var t = typeof value;
  if (value && (t === 'object' || t === 'function')) {
    var then = value.then;
    if (typeof then === 'function') {
      return then;
    }
  }
  return null;
}

and would go somewhere before my comment in my fulfill function, checking if the result argument has a .then property.

In the promisejs example Promise implementation, why does the implementation check to see if a resolved value has a .then property? What Promise usecase does this cover?

Caleb Jay
  • 2,159
  • 3
  • 32
  • 66
  • 1
    I have a feeling this is so you can't resolve a promise with another promise (or promise-like object). If you do, it will try to resolve that new promise, until you get a real value. Not 100% sure though. – Frank Modica Oct 30 '18 at 18:16
  • Hmm, I think the comments indicate this as well, something along the lines of "A promise can never be resolved with a promise." If I remember correctly, other libraries just throw an error if this happens, and check some other way, hence my confusion. – Caleb Jay Oct 30 '18 at 18:56
  • 1
    A promise [can't be *fulfilled* with another promise](https://stackoverflow.com/q/32168194/1048572). It can be [*resolved*](https://stackoverflow.com/q/29268569/1048572) with one, though - and it very often is. – Bergi Oct 30 '18 at 22:05
  • 1
    Actually, making the promise constructor use a `resolve` callback instead of a `fulfill` one was pretty useless. The [`resolve` functionality is only important for the `then` method](https://stackoverflow.com/a/17724387/1048572), when [the callback returns another promise](https://stackoverflow.com/a/22562045/1048572). – Bergi Oct 30 '18 at 22:09

0 Answers0