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.
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.
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.
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.
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.
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.
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:
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
.
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
});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With