【问题标题】:How to use $http promise response outside success handler如何在成功处理程序之外使用 $http 承诺响应
【发布时间】:2016-02-08 17:16:45
【问题描述】:
$scope.tempObject = {};

 $http({
   method: 'GET',
   url: '/myRestUrl'
}).then(function successCallback(response) {
   $scope.tempObject = response
   console.log("Temp Object in successCallback ", $scope.tempObject);
}, function errorCallback(response) {

});
console.log("Temp Object outside $http ", $scope.tempObject);

我收到了successCallback 的回复,但是 在$http 之外没有得到$scope.tempObject。它显示undefined

$http之后如何访问response$scope.tempObject

【问题讨论】:

  • $http get 是一个异步调用。成功回调之外的 console.log 执行的时间,不执行成功回调。这就是 $scope.tempObject 未定义的原因。
  • 但是如果我想在回调后使用$scope.tempObject,我该如何使用它。 ?
  • 我建议学习 Promises。本文将帮助您了解它的工作原理 - pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
  • 你可以在回调函数中做这些事情。为什么在外面需要 $scope.tempObject?
  • @varun 我在外面有一些数据,所以我想在这个函数之外使用成功回调response 的数据

标签: angularjs angular-promise angular-http


【解决方案1】:

但是如果我想在回调之后使用 $scope.tempObject 那么我该如何使用它。 ?

您需要从 httpPromise 中链接。保存 httpPromise 并将值返回到 onFullfilled 处理函数。

//save httpPromise for chaining
var httpPromise = $http({
   method: 'GET',
   url: '/myRestUrl'
}).then(function onFulfilledHandler(response) {

   $scope.tempObject = response

   console.log("Temp Object in successCallback ", $scope.tempObject);

   //return object for chaining
   return $scope.tempObject;

});

然后你的外部来自httpPromise。

httpPromise.then (function (tempObject) {
    console.log("Temp Object outside $http ", tempObject);
});

有关详细信息,请参阅AngularJS $q Service API Reference -- chaining promises

可以创建任意长度的链,并且由于可以使用另一个 Promise 来解决一个 Promise(这将进一步推迟其解决方案),因此可以在链中的任何点暂停/推迟对 Promise 的解决。这使得实现强大的 API 成为可能。1


解释基于 Promise 的异步操作

console.log("Part1");
console.log("Part2");
var promise = $http.get(url);
promise.then(function successHandler(response){
    console.log("Part3");
});
console.log("Part4");

“第 4 部分”的控制台日志不必等待数据从服务器返回。它在 XHR 启动 后立即执行。 “第 3 部分”的控制台日志位于成功处理函数中,该函数由 $q service 持有,并在数据从服务器到达并且 XHR 完成 后调用

演示

console.log("Part 1");
console.log("Part 2");
var promise = new Promise(r=>r());
promise.then(function() {
    console.log("Part 3");
});
console.log("Part *4*");

其他资源

【讨论】:

  • $q 帮助我。我使用了return $q(function ( resolve, reject ) { ... } ) 然后我解析了successCallback 对象。所以它的工作
  • 需要使用$q( (resolve, reject) => { } ),因为 $http 服务已经返回了一个承诺。这样做很容易出错并被视为anti-pattern
  • 这意味着如果我们使用 $timeout 函数有一些延迟,那么它也会获取完整的数据。例如 - $timeout(function () { console.log("Temp Object outside $http ", $scope.tempObject); }, 1000)
【解决方案2】:

$http 调用是异步调用。回调函数在返回响应时执行。同时,函数的其余部分继续执行并将 $scope.tempObject 记录为 {}。 当 $http 被解析时,只有 $scope.tempObject 被设置。 Angular 将使用两种方式自动绑定更改的值。

视图中的

{{tempObject}} 会自行更新。

如果你想在回调后使用 tempObject 那就这样做

then(function(data){
   onSuccess(data);
},function(){

});

function onSuccess(data){
// do something
}

【讨论】:

  • 我在成功回调中获取数据,我想在回调后使用它。
【解决方案3】:

在完成successCallback函数之前尝试使用$scope.$apply。另一种解决方案是更改 successCallback -> 函数:

$http({ method: 'GET', url: '/myRestUrl' }).then(function(success) { $scope.tempObject = success; console.log("Temp Object in successCallback ", $scope.tempObject); }, function(error) { }); 

【讨论】:

  • $apply 在这里没有帮助。因为它不是任何视图或范围的问题。问题基本上是我想在外面访问响应
  • 我在成功回调中使用了$watch,但它并没有反映出任何外部价值。最主要的是不需要看,因为我得到了正确的回应
  • 你尝试设置类似我帖子的成功功能?
猜你喜欢
  • 2021-04-10
  • 2016-02-06
  • 2021-01-24
  • 1970-01-01
  • 2017-07-28
  • 2022-11-10
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多