角度循环请求未定义

angular loop request undefined

本文关键字:未定义 请求 循环      更新时间:2023-09-26

$http.get("./data/web.json")请求成功并返回数组。当我通过执行请求来循环数组时,迭代器变量i将是未定义的?!那么,我如何访问返回数组并执行循环请求呢?

    <script>
        var ngApp = angular.module("webApp", ['xml'])
        .config(function ($httpProvider) {
            $httpProvider.interceptors.push('xmlHttpInterceptor');
          })
        .controller("webCtrl", function($scope, $http) {
            $http.get("./data/web.json")
            .success(function(response) {
                $scope.websites = response;
                for (i = 0; i < $scope.websites.length; i++){
                    $http.get('../api/alexa?url=' + $scope.websites[i].url)
                    .success(function(rsp) {
                        //$scope.websites[i].rank = rsp.data.POPULARITY.TEXT;
                        console.log($scope.websites[i]);
                    });
                }
                console.log(response);
            });
        });
    </script>
.controller("webCtrl", function ($scope, $http) {
  $http.get("./data/web.json")
    .success(function (response) {
      $scope.websites = response;
      for (i = 0; i < $scope.websites.length; i++) {
        $scope.processWebsites($scope.websites[i], i);
      }
    });
  $scope.processWebsites = function (website, index) {
    $http.get('../api/alexa?url=' + website.url)
      .success(function (rsp) {
        console.log($scope.websites[index]);
      });
  }
});

试试这个代码。这将创建一个新的执行上下文,从而消除由于异步执行而产生的任何无意的副作用。

您想访问i变量,但如果您的请求花费了大量时间,则循环不会等待它将进行ajax调用并在for循环之后执行结束你的i将是$scope.websites.length+1(因为i++),所以你会得到未定义来解决这个问题,你必须使用闭包函数

循环中的JavaScript闭包——简单实用的示例

var funcs = [];
function createfunc(i) {
    return function() {
        $http.get('../api/alexa?url=' + $scope.websites[i].url)
            .success(function(rsp) {
                //$scope.websites[i].rank = rsp.data.POPULARITY.TEXT;
                console.log($scope.websites[i]);
            });
    };
}
$http.get("./data/web.json")
    .success(function(response) {
        $scope.websites = response;
        for (i = 0; i < $scope.websites.length; i++) {
            funcs[i] = createfunc(i)
            $http.get('../api/alexa?url=' + $scope.websites[i].url)
                .success(function(rsp) {
                    //$scope.websites[i].rank = rsp.data.POPULARITY.TEXT;
                });
        }
        console.log(response);
    });
for (i = 0; i < funcs.length; i++) {
    funcs[i]();
}

我不确定您的响应json是什么样子,但它应该是键值对数组或单个键值对所以如果你有

[ {key:value},{key:value},{key:value}]

作为响应,假设密钥为url,在您的情况下为

它应该直接为您工作,现在您正在请求一个名为i的密钥那就是未定义的网站[i]。

试着做这个

foreach循环

i在您的第二次成功回调中没有定义,因为它是一个异步回调,当它被调用时,父作用域不再有效,因为它在执行时没有定义任何局部变量,您应该在for循环中定义迭代器,这样它将被正确地声明和提升

但您应该注意,由于它是一个异步回调,当循环在第一次回调之前结束的大多数机会都会被调用时,您将面临竞争条件,并且所有迭代中的迭代器值将是数组大小(最后一个值)

var a = [1, 2, 4]
for (var i = 0; i < a.length; i++) {
  var that = this;
  that.iterator = i;
  setTimeout(function() {
    alert(a[that.iterator]);
  }, 10);
}

我建议您聚合调用,并使用$q.all

使用聚合回调将所有调用一起处理