You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AngularJS中如何按顺序执行嵌套$http.get请求?

Fixing Nested $http.get Async Order Issues in AngularJS

Ah, I've run into this exact problem with AngularJS's asynchronous $http calls before—let me walk you through what's going wrong and how to fix it.

The Root Cause

The core issue here is that $http requests are asynchronous. When you loop through the first request's results and fire off a second $http.get for each item, the loop doesn't wait for each request to finish before moving on. By the time you try to use $scope.infoWithStatus, most (if not all) of those second requests are still in flight, leaving your array empty or only partially populated.

The Solution: Use $q.all to Coordinate Async Requests

AngularJS provides the $q service to manage Promises, which lets us wait for all our second requests to complete before assembling the final array. Here's how to adjust your code:

First, make sure you inject $q into your controller (along with $scope and $http). Then update your populateData function:

$scope.populateData = function() {
  $scope.infoWithStatus = [];
  
  // First request to get names
  $http.get("commonAppGet.jsp?sqlStr=select name from test where title_id=1")
    .then(function(resp) {
      const nameList = resp.data;
      
      // Create an array of Promises for each status request
      const statusPromises = nameList.map(function(name) {
        return $http.get(`commonAppGet.jsp?sqlStr=select status from test_status where name='${name}'`)
          .then(function(statusResp) {
            // Return the combined object we want for each item
            return {
              name: name,
              status: statusResp.data[0].status
            };
          });
      });
      
      // Wait for all status requests to complete
      return $q.all(statusPromises);
    })
    .then(function(allResults) {
      // All requests are done—assign the full array to scope
      $scope.infoWithStatus = allResults;
      console.log("All data loaded successfully:", $scope.infoWithStatus);
    })
    .catch(function(error) {
      // Handle any errors from either request
      console.error("Request failed:", error);
    });
};

How This Works

  1. Map instead of ForEach: We use map to transform each name into a Promise (from the second $http call). This gives us an array of Promises we can track.
  2. $q.all for Coordination: $q.all(statusPromises) waits until every Promise in the array resolves. Once they do, it passes an array of all resolved values (our combined name+status objects) to the next .then() callback.
  3. Guaranteed Full Population: By the time we assign allResults to $scope.infoWithStatus, every second request has finished, so your array is complete and ready to use.

Bonus Tips

  • Parallel Efficiency: This approach runs all second requests in parallel, which is much faster than running them one after another. If you need sequential execution (e.g., due to backend rate limits), you can chain Promises instead, but parallel is almost always preferable here.
  • Security Alert: Directly concatenating name into your SQL string is a critical SQL injection vulnerability! Modify your backend to accept parameters safely, and pass the name as a request parameter instead of embedding it in sqlStr. For example:
    $http.get("commonAppGet.jsp", {
      params: {
        query: "select status from test_status where name=?",
        nameParam: name
      }
    })
    
    Let your backend handle parameterizing the query to avoid attacks.

内容的提问来源于stack exchange,提问作者Nishant Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:20:51