I have an array of objects coming back from $http.get that I need to do three different autonomous post processes on. I believe I can use $q.all to execute the post processes in parallel.
I see a ton of examples that use $timeout/setTimeout that follow this pattern:
function doSomethingAsync() {
var deferred = $q.defer();
setTimeout(function() {
deferred.resolve('hello world');
}, 500);
return deferred.promise;
}
doSomethingAsync().then(function(val) {
console.log('Promise Resolved!', val);
});
I'm new to javascript, but this doesn't get at the heart of my problem. The $timeout and setTimeout function are already asynchronous and therefore the doSomethingAsync just falls through returning the promise...no actual work was done inline.
In the following example, I don't understand how the function returns the promise immediately upon execution. Will the "return deferred.promise" execute before the loop is complete? Wouldn't the function be forced to execute the loop first and then the return statement?
function doSomethingRealWorkAsync() {
var deferred = $q.defer();
//loop through the items in an array and perform some heavy lifting that will take time
deferred.resolve('Done!');
return deferred.promise;
}
doSomethingRealWorkAsync().then(function(val) {
console.log('Promise Resolved!', val);
});
Every example I've looked at uses an async process (either $timeout or setTimeout) to simulate work being done. What about real work? What if I have multiple long running processes that I want to run in parallel?
Using the above pattern would yield the following code, but I can't imagine it working correctly. Will this work? If not, why? If so, how?
$scope.items = [{}];
$scope.initialized = false;
function doOneThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyA = 'this';
}
deferred.resolve('Done with One Thing!');
return deferred.promise;
}
function doAnotherThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyB = 'that';
}
deferred.resolve('Done with Another Thing!');
return deferred.promise;
}
function doYetAnotherThingToItemsAsync() {
var deferred = $q.defer();
for (var i in items) {
items[i].propertyC = 'I smell a cat';
}
deferred.resolve('Done with Yet Another Thing!');
return deferred.promise;
}
function getItems () {
$http.get("/api/widgets", { timeout: 0 })
.success(function (data) {
items = data.items;
$q.all([doOneThingToItemsAsync(),
doAnotherThingToItemsAsync(),
doYetAnotherThingToItemsAsync()])
.then(function(result) {
for (var i in result) {
console.log(result[i]);
}
initialized = true;
});
})
.error(function (data) {
if (data.errorMessage) {
console.log("There was a problem retrieving your data: \n" + data.errorMessage + "\nPlease try again.");
} else {
console.log("There was a problem retrieving your data. Please try again.");
}
});
}
Does the browser's interpreter evaluate the type being returned on the function (in this case a promise) and allow you to call methods on that type (e.g. then, success, error) passing in callback functions that will be executed upon executing deferred.resolve, deferred.reject, etc.?