With promise API, how to send two asynchronous request in parallel, and resolve the combined result as the response.
var get = function(id){
var res1, res2;
var deferred = $q.defer();
Db.get(id, "abc")
.then(function (d) {
//deferred.resolve(d));
res1 = d;
}, function (e) {
//error
});
Db.get(id, "def")
.then(function (d) {
//deferred.resolve(d));
res2 = d;
}, function (e) {
//error
});
//?????? how to return {res1:res1 , res2: res2}
return deferred.promise;
};
now, when I call get() like
get(123).then(function(d)){
// d= {res1: res1, res2: res2}
},
...
I need to get the combined result as indicated. How to do this with Angular promise API?
A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.
Promise.all() The Promise.all() method takes an iterable of promises as an input, and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will fulfill when all of the input's promises have fulfilled, or if the input iterable contains no promises.
We'll start by providing the code, and then we'll walk through the changes. let promise = new Promise(function(resolve, reject) { let request = new XMLHttpRequest(); const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.API_KEY}`; request.
As @Matt said, you need to use $q.all
, but the usage isn't quite right. AngularJS doesn't support .done
and .fail
and they don't work quite like that anyway in that there's no such thing as a promise for multiple values, instead you just have a promise for an array.
If you were writing this using the full Q we would write:
var get = function (id) {
return Q.all([Db.get(id, "abc"), Db.get(id, "def")])
.spread(function (res1, res2) {
return {res1: res1, res2: res2};
});//the error case is handled automatically
};
In this case, .spread
acts like .then
except that it spreads the results of an array for a promise out over the arguments of its onFulfilled
function. To change this to use the promise methods from AngularJS we just need to make do without .spread
. This leads to the following solution:
var get = function (id) {
return $q.all([Db.get(id, "abc"), Db.get(id, "def")])
.then(function (res) {
return {res1: res[0], res2: res[1]};
});//the error case is handled automatically
};
The beauty of this is that we are freed from handling all the nitty grity of error propagation and storing the partial results because .then
acts as a filter. If you leave out the error handler, it automatically propagates any errors. This means that if either of the input promises are rejected, the result will be rejected. If both promises are fulfilled successfully, res is the array of those resolution values.
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