3组链式$http.get异步调用的实现合理性及执行时机问询
Hi Etienne! Great question—let's walk through your code and concerns one by one.
Is your implementation reasonable?
Your core approach is solid! You’re correctly using chained promises for each attribute’s two-step request, and $q.all() to wait for all groups to finish before aggregating data. That’s exactly the right pattern for this kind of parallel + sequential async work.
That said, you can clean up the code a bit by avoiding the deferred anti-pattern. Since $q.all() returns a promise itself, you don’t need to manually create a deferred object—you can just return the result of $q.all().then(...) directly. Here’s the optimized version:
function initChartData(starttime, endtime) { var attrURLs = [baseURL + '|Attribute1', baseURL + '|Attribute2', baseURL + '|Attribute3' ]; var dateFormat = 'dd-MMM-yyyy HH:mm'; var promises = attrURLs.map(function (url) { // First request: get attribute ID return $http.get(url) .then(function (response) { // Second request: fetch data using the ID var data = response.data; return $http.get(data.Links.GetData + '?starttime=' + $filter('date')(starttime, dateFormat) + '&endtime=' + sEndTime); }); }); return $q.all(promises) .then(function (responses) { // Aggregate all the final data points return responses.map(function (resp) { return resp.data.data; }); }); }
This does the exact same work but is more concise and follows Angular promise best practices.
Are the 3 groups of chained requests asynchronous? And when do the second requests fire?
Let’s break down the execution flow clearly:
- The 3 groups run in parallel asynchronously: As soon as the loop (either
angular.forEachormapin the optimized code) processes eachattrURL, it kicks off the first$http.getfor that group. All three initial requests are sent out almost immediately—they don’t wait for each other to finish. - Within each group, the second request is sequential: For any single group, the second
$http.getonly runs after that group’s first request successfully returns. So Group 1’s second request starts right after Group 1’s first finishes, Group 2’s second starts right after Group 2’s first finishes, etc. There’s no waiting for other groups’ first requests to complete before starting a group’s second request.
Final takeaway
Your original code works correctly, and the async behavior is exactly what you’d want here. The only improvement is trimming the unnecessary deferred object to make the code cleaner.
内容的提问来源于stack exchange,提问作者Menoto

