我对Ajax和Promise的成功回调感到困惑。
让我试着通过一个例子来解释我的困惑。
$http.get("https://someapi.com").success(function (){})
在上面的代码中,成功了我们的回调函数,它将在异步操作完成时执行..对吗?
现在来到Promise。
我们创建了一个承诺,即处理成功和失败(解决和拒绝)
现在我的问题是,当我们在Ajax中回调提供时,为什么我们需要承诺?
答案 0 :(得分:1)
Promises允许能够使用回调的结果和/或将多个调用链接在一起来操纵结果。随着async / await的引入,它可以使异步代码变得更加简单。
使用回调可以完成,但是有很多嵌套和潜在的混淆。
使用回调:
$http.get('https://something.com/rest/returns5').success(function(result) {
if (result) {
var finalValue = result - 4;
// to use the result you'll need another nested callback here
callback(finalValue); // what scope did this come from? where did this come from? :-)
}
});
承诺:
$http.get('https://something.com/rest/returns5')
.then(function(result) {
return result - 4;
})
.then(function(result) {
// use the result from the previous chained promise call (result - 4)
});
答案 1 :(得分:1)
使用promises的好处就是它们为异步任务提供了一个功能强大的通用接口。
通用接口(任何通用接口)的主要好处是您可以编写和使用对promises进行操作的更高级别的函数。仅举一个例子,许多promise库提供了一个函数,通常称为all
,它接受一组promise,并返回一个封装所有promise的新promise。然后你可以写下这样的东西:
promise.all(promise1, promise2).then(function (value1, value2) {
// blah blah
});
而不是这个金字塔代码
promise1.then(function (value1) {
promise2.then(function (value2) {
// blah blah
});
});
当然,如果您使用具有某些已知通用接口的异步任务,则只能使用all
之类的函数。如果某些方法具有.then
方法,某些方法具有.success
方法,则不可能。等等。
promise
接口有其他有用的属性,例如promise上的.then
方法返回一个promise - 如果你传递的回调返回一个promise,.then
方法返回实际上等待回调返回的承诺的承诺。换句话说:
// p1 is a promise that resolves to 1, when somePromise resolves
var p1 = somePromise.then(function (value) {
return 1;
});
// p2 is a promise that resolves to what someOtherPromise resolves to,
// not to someOtherPromise itself
var p2 = somePromise.then(function (value) {
return someOtherPromise;
});
这使得一个接一个地进行一系列HTTP调用变得简单易行。
使用promises也有一些缺点......按照惯例,它们将你的回调包装在try / catch块中,所以如果抛出异常就会被捕获,有时会被捕获。
somePromise.then(function (value) {
throw 'error';
}).catch(function (error) {
// without this catch block, the error may be eaten invisibly
console.error(error);
});
总而言之,promise只是一个用于管理异步任务的广泛使用的接口。如果你愿意,可以使用它,如果你不愿意,请不要使用它。