AngularJS 如何将$http请求响应存入变量 解决undefined及同步调用问题
问题根因
你遇到的undefined问题完全是因为对AngularJS $http的异步执行逻辑不熟悉:
$http.get()发起的请求默认是完全异步的,代码不会等待响应返回就继续顺次执行后续逻辑- 实际执行顺序为:调用
$http.get()发出请求 → 立刻执行alert()、拼接content的代码 → 等网络响应回来之后,才触发success回调给$scope.data.submissionFileID赋值
因此当你执行alert的时候,回调根本没运行,$scope.data.submissionFileID自然是未定义的状态 - 你提到的“把请求改成同步”的需求,本质上和JS的运行机制、AngularJS的设计初衷是冲突的:同步请求会完全阻塞浏览器主线程,导致页面卡死无法交互,除非极端特殊场景,否则不推荐这么做。
最优修改方案(官方推荐)
把所有依赖接口响应的逻辑,全部挪到请求的成功回调内部,等拿到响应、完成变量赋值后再执行后续操作,完全不需要改成同步:
$scope.openWindow = function (e) { var url = '/Submission/GetSubmissionFileInfo?' + 'id=' + SubmissionID; $http.get(url).success(function (response) { // 响应返回后先完成变量赋值 $scope.data.submissionFileID = response; // 所有依赖该变量的逻辑,全部放到回调内执行 alert($scope.data.submissionFileID); var content = "<h7><b>Created at </b>" + $scope.data.submissionFileID + "</h7><br><br>"; // 后续使用content打开窗口、绑定页面元素的逻辑也统一放在这里即可 }); }
特殊场景的同步请求实现(非必要不使用)
如果确实有强需求必须阻塞代码等待接口返回,可以在$http.get的配置项里关闭异步开关,写法如下:
$scope.openWindow = function (e) { var url = '/Submission/GetSubmissionFileInfo?' + 'id=' + SubmissionID; // 配置为同步请求,阻塞主线程直到响应返回 $http.get(url, { async: false }).success(function (response) { $scope.data.submissionFileID = response; }); // 由于同步阻塞特性,执行到这里时回调已经运行完成,变量已经完成赋值 alert($scope.data.submissionFileID); var content = "<h7><b>Created at </b>" + $scope.data.submissionFileID + "</h7><br><br>"; }
注意事项
- 同步XHR是现代浏览器逐步淘汰的用法,主流浏览器会在控制台输出废弃警告,接口响应稍慢就会导致页面完全卡死,交互失效,仅适合响应极快的本地接口场景
- 请提前在控制器作用域内初始化
$scope.data = {},如果$scope.data本身是未定义状态,哪怕放到回调内赋值也会抛出类型错误
内容的提问来源于stack exchange,提问作者Partha
相关产品推荐
相关产品推荐

