Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does promise.join() take a function as its last parameter?

Say I have a step in a procedure that requires the retrieval of two objects. I would use join() to coordinate the retrievals:

return promise.join(retrieveA(), retrieveB())
           .spread(function(A, B) {
               // create something out of A and B
           });

The documentation shows that you can also pass the handler as the last parameter:

return promise.join(retrieveA(), retrieveB(), function(A, B) {
           // create something out of A and B
       });

I'm curious as to what the rationale behind the existence of this option.

like image 596
cleong Avatar asked Apr 13 '15 16:04

cleong


People also ask

What does Promise () method do?

The . promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. By default, type is "fx" , which means the returned Promise is resolved when all animations of the selected elements have completed.

Does Promise all guarantee order?

One interesting thing about Promise. all is that the order of the promises is maintained. The first promise in the array will get resolved to the first element of the output array, the second promise will be a second element in the output array and so on.

What is Promise resolve () then?

The Promise. resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise. resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.

How does Promise work in event loop?

A promise represents the completion of an asynchronous function. It is an object that might return a value in the future. It accomplishes the same basic goal as a callback function, but with many additional features and a more readable syntax.


2 Answers

you can also pass the handler as the last parameter. I'm curious as to what the rationale behind the existence of this option.

It is not an "option". It's the sole purpose of the join function.

Promise.join(promiseA, promiseB, …, function(a, b, …) { … })

is exactly equivalent to

Promise.all([promiseA, promiseB, …]).spread(function(a, b, …) { … })

But, as mentioned in the documentation, it

is much easier (and more performant) to use when you have a fixed amount of discrete promises

It relieves you of needing to use that array literal, and it doesn't need to create that intermediate promise object for the array result.

like image 82
Bergi Avatar answered Oct 01 '22 10:10

Bergi


Fact time: The reason .join was added was to make @spion happy. Not without reason though, using .join means you have a static and known number of promise which makes using it with TypeScript a lot easier. Petka (Esailija) liked the idea and also the fact it can be optimised further because it doesn't have to abide to weird guarantees the other form does have to abide to.

Over time, people started (at least me) using it for other use cases - namely using promises as proxies.

So, let's talk about what it does better:

Static Analysis

It's hard to statically analyse Promise.all since it works on an array with an unknown types of promises of potentially different types. Promise.join can be typed since it can be seen as taking a tuple - so for example for the 3 promises case you can give it a type signature of (Promise<S>, Promise<U>, Promise<T>, ((S,U,T) -> Promise<K> | K)) -> Promise<K> which simply can't be done in a type safe way for Promise.all.

Proxying

It's very clean to use when writing promise code in the proxying style:

var user = getUser();
var comments = user.then(getComments);
var related = Promise.join(user, comments, getRelated);
Promise.join(user, comments, related, (user, comments, related) => {
     // use all 3 here
});

It's faster

Since it doesn't need to produce the value of the given promises cached and to keep all the checks .all(...).spread(...) does - it'll perform slightly faster.

But... you really usually shouldn't care.

like image 32
Benjamin Gruenbaum Avatar answered Oct 01 '22 09:10

Benjamin Gruenbaum