I have angular code that calls two separate backend services via $ http.get. The backend is ASP.NET MVC 5.
I call the services through $ http.get, and since I need to respond from both services before continuing, I will complete the returned promises in $ q.all. However, when resolving promises via $ q.all, there is apparently a lot of overhead compared to resolving promises sequentially (i.e., calling the second service in the last callback of the first promise).
Overhead appears in TTFB (time to first byte).
I cannot understand why $ q.all will be slower than consistently expecting one promise to be resolved before the next begins. In fact, I thought $ q.all would be faster, as this would allow me to start a second service call before the first resolves.
Read more about implementation details.
These backend services are fairly lightweight:
ProductsController:
[HttpGet]
public Dictionary<string, PriceListTypeDto> GetPriceListTypesForProducts([FromUri] List<string> productErpIds)
{
}
UserController:
[HttpGet]
public int? GetUserOrganizationId()
{
}
Javascript functions calling these services:
var addPriceListTypes = function (replacementInfoObjects, productErpIds) {
return productService.getPriceListTypesForProducts(productErpIds)
.then(function (response) {
})
.catch(function () {
});
}
var addOrganizationSpecificDetails = function (replacementInfoObjects) {
return userContextService.getUserOrganizationId()
.then(function (response) {
})
.catch(function () {
});
};
Work with promises:
Option 1: takes ~ 600 ms before calling $ q.all.then.
mapping-service.js:
var deferredResult = $q.defer();
var orgDetailsPromise = addOrganizationSpecificDetails(productInfoObjects);
var priceListPromise = addPriceListTypes(products, productErpIds);
$q.all([orgDetailsPromise, priceListPromise])
.then(function () {
deferredResult.resolve(productInfoObjects);
}).catch(function () {
deferredResult.reject();
});
return deferredResult.promise;
Performance through Chrome devtools: 
Option 2: takes ~ 250 ms before both promises are resolved:
mapping-service.js:
var deferredResult = $q.defer();
addOrganizationSpecificDetails(productInfoObjects)
.then(function () {
addPriceListTypes(productInfoObjects, productErpIds)
.then(function () {
deferredResult.resolve(productInfoObjects);
})
.catch(function () {
deferredResult.reject();
});
})
.catch(function () {
deferredResult.reject();
});
return deferredResult.promise;
Performance through Chrome devtools: 
Where does the overhead in option 1 come from? What did I miss? I am completely here. Please let me know if you need more information.