我在从jQuery转换几年后正在学习AngularJS。有些位更加直观。有些不那么多:)。
我试图了解承诺的使用,特别是使用$ http的$ q,并且似乎没有太多关于这两个组合的信息,我可以找到。
为什么我会使用promises代替成功/错误回调?他们都在现实中使用回调,那么为什么承诺会更好?例如。我可以设置一个get(...)
函数,如下所示:
function get(url, success, error) {
success = success || function () {};
error = error || function () {};
$http.get(url)
.success(function (data) {
success(data);
})
.error(function (error) {
error(error);
});
}
get('http://myservice.com/JSON/',
function () {
// do something with data
},
function () {
// display an error
}
);
哪个好(?)因为它让我完全控制正在发生的事情。如果我拨打get(...)
,那么我可以控制get
被调用的任何成功/错误。
如果我将此转换为使用承诺,那么我得到:
function get(url) {
return $http.get(url)
.then(function (data) {
return data;
},
function (error) {
return error;
});
}
get('http://myservice.com/JSON/')
.then(function (data) {
// do something with data
});
// cannot handle my errors?
哪个是浓缩的,我同意;我们也不必明确担心成功/错误回调,但我似乎已经失去了对我的错误回调的控制 - 因为我无法配置第二个回调来处理错误。
这意味着如果我在一个可供多个控制器使用的服务中使用此功能,那么我无法更新UI以提醒用户出错。
我错过了什么吗?承诺是首选的是有原因吗?我找不到一个例子。
答案 0 :(得分:24)
通常,您将使用回调来处理Javascript中的异步任务;
$.get('path/to/data', function(data) {
console.log(data);
});
它工作正常,但是当你进入什么叫做“回调地狱”时会开始变得复杂;
$.get('path/to/data', function(data) {
$.get('path/to/data2' + data, function(data2) {
$.get('path/to/data3' + data2, function(data3) {
manipulate(data, data2, data3);
}, errorCb);
}, errorCb);
}, errorCb);
替代方案是使用promises和deferred对象;
Deferreds - representing units of work
Promises - representing data from those Deferreds
坚持这个议程可以在每个极端的asynctask案例中为你提供帮助:
您的任务是使用$ q和$ http
处理的最简单的任务function get(url) {
var deferred = $q.defer();
$http.get(url)
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
调用服务功能是相同的
get('http://myservice.com/JSON/')
.then(function (data) {
// do something with data
});
// cannot handle my errors?
答案 1 :(得分:1)
您可以像这样处理错误:
get('http://myservice.com/JSON/')
.then(function (data) {
// do something with data
},
function (error) {
//do something with error
});
但遗憾的是,由于您已经发现错误,因此最终错误不会被触发。成功也会遇到同样的问题。
要实现这一点,你需要使用$ q。
function get(url) {
var deferred = $q.defer();
$http.get(url)
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
deferred.reject(error);
});
return deferred.promise;
}
此外,无需传递成功和错误函数,因为您可以使用promises。