I race requests in my system and want to return whoever is the fastest. However, the fastest promise could also technically throw an error despite the slower promises being successful.
How can I race promises and keep evaluating if the fastest one was a reject?
const myPromises = [p1, p2, p3]
const winner = Promise.race(myPromises) // this fails if winning promise rejects
p1 wins but returns 500 so promise rejects
p2 comes in second with a 200, return p2
You want to use Promise.any() instead.
This will resolve when the first promise you pass it resolves and will ignore rejected promises unless all of them reject (none resolved).
So, if the first two in your example reject immediately, it will wait for the outcome of the third promise.
It sounds like Promise.any() does exactly what you want.
(I think I learned this, it is that .then returns a promise even if it is not run, i never knew this, thank you)
Please forgive me if this is a dumb question but I simply don't get this, I've googled this many times but those articles only talk about Promise very briefly like how to create one, how to resolve, how to .then and stuff.
I'm confused about promise chaining.
This is my code:
let p = new Promise(function (resolve, reject){
let value = 19;
if(!value){
resolve(value)
} else {
reject(value)
}
})
p.then(x => {console.log(x*x); throw false})
.then(null, x => console.log(x))
//19
This code prints 19 and I have no clue why?.
I do know every .then returns a promise but in this case, p.then shouldn't have even run because the promise is not resolved. Now in a way, it seems that didnt run but if so, why did the second .then run?
Our first .then didn't run, it didnt run any promise whatsoever, so nothing should have displayed.
Now unless 2nd .then is working the same as p.then() which I hope it doesnt because that will only create more confusions, I dont understand why will the 2nd .then run?.
I'm sorry again if my question or english bad but I'm really curious about this.
The .then function takes two functions as parameters, one which is called when the Promise resolves and one when it rejects. It returns a new Promise which gets resolved or rejected with whatever value the function which was executed returns (or throws). If no handler was executed, the Promise will just resolve or reject with the same value the Promise .then was called on.
In your example the first .then call only received one argument, and as the Promise rejects it won't be executed. Therefore the Promise it returns will also reject, and thus the second argument will be executed.
// some examples
Promise.resolve()
.then(called, notCalled);
Promise.reject()
.then(notCalled, called);
Promise.resolve(1)
.then(null, notCalled)
.then(it => it + 1, notCalled)
.then(called, notCalled);
Promise.reject(1)
.then(notCalled, null)
.then(notCalled, it => it + 1)
.then(called, notCalled);
A Promise can be in one of these states:
pending -> initial state, neither fulfilled nor rejected.
fulfilled -> the operation was completed successfully.
rejected -> the operation failed.
In your code sample, the promise is being rejected (since if value is a truthy condition).
The then method accepts two arguments:
p.then(onFulfilled[, onRejected]);
p.then(value => {
// fulfillment
}, reason => {
// rejection
});
Since the then is chainable, the reject get's fired on the second chained then which is the line of code:
x => console.log(x)
Hence, printing the value 19.
Looking at your questions on the two answers above (and also, perhaps the fact that you didn't selected either answer as correct), I wonder if you're still confused about this.
Here is an explanation based on stepping through your code:
p.then(x => {console.log(x*x); throw false})
.then(null, x => console.log(x))
Reading one token at a time:
p is a promise. It has the code as you defined for p: let p = new Promise ...
We immediately call p's then function. This runs the code in p (since p has not yet been run -- promises only run once). Your code in p is a bit confusing because it defines value to be 19, but then it says if ( !value ) ... which means "if value has no value (i.e., is falsey)". In your cause value does have a value, 19. So that causes the else part to run, which says reject(value). This moves p from an "undetermined" state to a rejected state.
Back in your main code, the then clause (the first one), only has one argument. A then clause typically has two arguments, one for code to run if the promise resolves (succeeds), and one if it fails. In your case you only provided one argument to your first then call. Since p was rejected, JavaScript doesn't run the code in the first then, but (as you point out from your learning in bold) it does still return another promise.
Now that the promise from the first then has been determined, we invoke the chained (second) then. Jonas Wilms points out the key fact: If no handler was executed, the Promise will just resolve or reject with the same value the Promise .then was called on. So that means the second then gets the same result as the first then, rejected.
Since the second then has two arguments, JavaScript runs the second one (the one for the rejection case), which prints 19.
I have a method that returns a promise.
doStuf() {
return somePromise
.then(...)
.catch(e => {...})
}
I want to write a test that makes sure the promise returned by the doStuff method has a catch method.
How to do that ?
That is not a useful thing to test. Consider that doStuf may be refactored later into something more multi-layered, where several then-catch chains may exist, or the implementation will change in some other ways.
You don't actually want to test the implementation, because you can simply look at it to see whether the promise has a catch. No, you want to test the behaviour of doStuf. You want to assert that doStuf returns a promise, and that that promise returns the expected value given certain input. E.g.:
doStuf('foo').then(r => /* assert r equals expected outcome */)
doStuf('bar').catch(r => /* assert r equals expected error */)
As I know, Promises are used to represent success/failure of an asynchronous operation. When I am looking into one of my project, all the functions are wrapping the final result in 'Promise.resolve'. I am not understanding, what is the use of wrapping all the function results in 'Promise.resolve'. Is there any use case here?
For example, all the functions are following below template.
process = (data) => {
//Perform some operations.
return Promise.resolve(result);
}
The only reason to use Promise.resolve is converting a value that might be a promise to a promise.
Promise.resolve(value) is a convenience method that does new Promise(resolve => resolve(value). If the value is a promise it will be returned, if it is a promise from a userland promise library it will be converted to a native promise. If it is a plain value it will be converted for a promise fulfilled with that value.
Promise.resolve(5); // returns a promise fulfilled with the number 5.
This is useful in several cases, for example:
- If a function might return a promise, it should always return a promise - so for example if you have a cached value it might need to be Promise.resolved.
- If there are multiple implementations of functionality and some are synchronous - it creates a uniform interface.
Note that in practice with async functions this is not needed so much anymore since an async function always returns a promise - even if you return a plain value (in fact, whatever you return from an async function is Promise.resolved implicitly).
Also note that in particular you shouldn't make functions return promises if all they do is synchronous computation since a function returning a promise implies I/O in JavaScript.
I have read the documentation of $q.when in the angularjs official docs, but I donĀ“t understand yet what is the purpose of $q.when and its way to manage a response.
$q.when takes a promise or a plain value and converts it to a promise. If it already was a promise it simply returns it.
It is useful if you don't know whether the object you're dealing with is a promise or not. For example, you might have an if/else statement where one path returns a promise but another path returns a value directly. In that case, it would be good to use $q.when to handle the return such that you get a value out of it whether it's a promise or not.
For example:
function getData(){
if(cachedData) return $q.when(cachedData); // converts to promise
else return $http.get("/dataUrl"); // make HTTP request, returns promise
}