Why does the Promise constructor require a function that calls 'resolve' when complete, but 'then' does not - it returns a value instead?

后端 未结 4 1948
说谎
说谎 2020-12-04 09:11

As I plunge into studying Promises, my understanding has halted on the following question that I do not find discussed (all I find are specific discussions of t

4条回答
  •  情书的邮戳
    2020-12-04 10:09

    There is no correspondence between the Promise constructor and the then method because they are two independent things, designed for different purposes.

    The Promise constructor is only used for promisifying1 asynchronous functions. Indeed, as you say, it is built on invoking resolve/reject callbacks to asynchronously send values, and there are no return values in that case.

    That the Promise constructor itself does take this "resolver" callback (to which it synchronously passes resolve and reject) is in fact an enhancement of the older deferred pattern, and bears no intended similarity to the then callbacks.

    var p = new Promise(function(res, rej) {    |    var def = Promise.Deferred();
        setTimeout(res, 100);                   |    setTimeout(def.resolve, 100);
    });                                         |    var p = def.promise;
    

    The then callbacks in contrast are classical asynchronous callbacks, with the additional feature that you can return from them. They are being invoked asynchronously to receive values.

    p.then(function(val) { … });
    

    To sum up the differences:

    • Promise is a constructor, while then is a method
    • Promise takes one callback, while then takes up to two
    • Promise invokes its callback synchronously, while then invokes its callbacks asynchronously
    • Promise always invokes its callback,
      then might not invoke its callbacks (if the promise is not fulfilled/rejected)
    • Promise passes the capabilities to resolve/reject a promise to the callback,
      then passes the result value / rejection reason of the promise it was called on
    • Promise invokes its callback for the purpose of executing side effects (call reject/resolve),
      then invokes its callbacks for their result values (for chaining)

    Yes, both do return promises, though they share that trait with many other functions (Promise.resolve, Promise.reject, fetch, …). In fact all of these are based on the same promise construction and resolve/reject capabilities that also the Promise constructor provides, though that's not their primary purpose. then basically offers the ability to attach onFulfilled/onRejected callbacks to an existing promise, which is rather diametral to the Promise constructor.

    That both utilise callbacks is just coincidential - not a historical fluke, but rather coadaption of a language feature.

    1: Ideally, you would never need this because all natively asynchronous APIs return promises

提交回复
热议问题