如何使用 $q 多重回调 AngularJs 中的一个 promise?
How to multi-callback a promise in AngularJs with $q?
我正在使用下面的代码来简化后端请求,但我没有理解如何调用成功方法或错误方法。
如何达到代码中注释的预期行为?
app.factory('REST', function ($http, $q, sweetAlert) {
return {
load: function (module, action, data) {
var deferred = $q.defer();
var promise = deferred.promise;
$http
.post('/api/'+module+'.php?action='+action, data)
.success(function (data) {
if(data.error)
{
sweetAlert.swal({
title: "Error",
text: data.error,
type: "warning"
});
//HERE I WANT TO CALL .error(details)
}
else
deferred.resolve(data.result);
}).error(function () {
//HERE I WANT TO CALL .error(details)
});
promise.success = function(fn) {
promise.then(fn);
return promise;
}
return promise;
}
};
});
这是使用上面代码的代码:
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload).success(function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
}).error(function(data) { //THIS SHOULD BE CALLED
$scope.loading = false;
});
}
按如下方式更新您的代码
app.factory('REST', function ($http, $q, sweetAlert) {
return {
load: function (module, action, data) {
var deferred = $q.defer();
$http.post('/api/'+module+'.php?action='+action, data)
.success(function (data) {
if(data.error)
{
sweetAlert.swal({
title: "Error",
text: data.error,
type: "warning"
});
//HERE I WANT TO CALL .error(details)
deferred.reject(data.error);
}
else{
deferred.resolve(data.result);
}
})
.error(function (error) {
//HERE I WANT TO CALL .error(details)
deferred.reject(error);
});
return defferred.promise;
}
};
});
对于您的控制器
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload).then(
function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
},
function(error) {
$scope.loading = false;
});
}
首先,我强烈建议您不要将 .success
附加到您 return 的承诺上。这不是 Promises/A-compliant,它与 .then
的细微差别(由 $http
实现)会引起很多混淆。只是 return 一个纯粹的承诺。
除此之外,还有几点需要注意:
1) 你不需要另一个 $q.defer
和 deferred.resolve()
- 只需链接到 $http
和 [= 的原始承诺18=] 结果承诺。 (参见 deferred anti-pattern)
2) 拒绝一个 promise - 也就是说,触发 .catch
(不是 .error
- 见上文关于细微差别) - 你应该 return $q.reject()
.
以上所有产生以下结果:
app.factory('REST', function($http, $q, sweetAlert){
return {
load: function(module, action, data) {
// this "return" returns the promise of $http.then
return $http.post('/api/' + module + '.php?action=' + action, data)
.then(function(response) {
var data = response.data; // .then gets a response, unlike $http.success
if (data.error) {
sweetAlert.swal({
title: "Error",
text: data.error,
type: "warning"
});
//HERE I WANT TO CALL .error(details)
return $q.reject(data.error);
}
return data.result; // what you would have "resolved"
});
}
};
})
然后,正如我上面所说,像使用 promises 一样使用 .then
/.catch
:
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload)
.then(function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
})
.catch(function(error) {
$scope.loading = false;
});
}
我正在使用下面的代码来简化后端请求,但我没有理解如何调用成功方法或错误方法。
如何达到代码中注释的预期行为?
app.factory('REST', function ($http, $q, sweetAlert) { return { load: function (module, action, data) { var deferred = $q.defer(); var promise = deferred.promise; $http .post('/api/'+module+'.php?action='+action, data) .success(function (data) { if(data.error) { sweetAlert.swal({ title: "Error", text: data.error, type: "warning" }); //HERE I WANT TO CALL .error(details) } else deferred.resolve(data.result); }).error(function () { //HERE I WANT TO CALL .error(details) }); promise.success = function(fn) { promise.then(fn); return promise; } return promise; } }; });
这是使用上面代码的代码:
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload).success(function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
}).error(function(data) { //THIS SHOULD BE CALLED
$scope.loading = false;
});
}
按如下方式更新您的代码
app.factory('REST', function ($http, $q, sweetAlert) {
return {
load: function (module, action, data) {
var deferred = $q.defer();
$http.post('/api/'+module+'.php?action='+action, data)
.success(function (data) {
if(data.error)
{
sweetAlert.swal({
title: "Error",
text: data.error,
type: "warning"
});
//HERE I WANT TO CALL .error(details)
deferred.reject(data.error);
}
else{
deferred.resolve(data.result);
}
})
.error(function (error) {
//HERE I WANT TO CALL .error(details)
deferred.reject(error);
});
return defferred.promise;
}
};
});
对于您的控制器
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload).then(
function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
},
function(error) {
$scope.loading = false;
});
}
首先,我强烈建议您不要将 .success
附加到您 return 的承诺上。这不是 Promises/A-compliant,它与 .then
的细微差别(由 $http
实现)会引起很多混淆。只是 return 一个纯粹的承诺。
除此之外,还有几点需要注意:
1) 你不需要另一个 $q.defer
和 deferred.resolve()
- 只需链接到 $http
和 [= 的原始承诺18=] 结果承诺。 (参见 deferred anti-pattern)
2) 拒绝一个 promise - 也就是说,触发 .catch
(不是 .error
- 见上文关于细微差别) - 你应该 return $q.reject()
.
以上所有产生以下结果:
app.factory('REST', function($http, $q, sweetAlert){
return {
load: function(module, action, data) {
// this "return" returns the promise of $http.then
return $http.post('/api/' + module + '.php?action=' + action, data)
.then(function(response) {
var data = response.data; // .then gets a response, unlike $http.success
if (data.error) {
sweetAlert.swal({
title: "Error",
text: data.error,
type: "warning"
});
//HERE I WANT TO CALL .error(details)
return $q.reject(data.error);
}
return data.result; // what you would have "resolved"
});
}
};
})
然后,正如我上面所说,像使用 promises 一样使用 .then
/.catch
:
$scope.login = function () {
$scope.loading = true;
var payload = {'credentials': $scope.logindata};
REST.load('access', 'login', payload)
.then(function(data) {
if(data.redirect)
$state.go(data.redirect);
$scope.loading = false;
})
.catch(function(error) {
$scope.loading = false;
});
}