回调还是承诺?
这个问题在这里已经有了答案:
承诺建立在回调之上。 后者更原始,更一般,当你需要做一些复杂的事情时需要更多的工作。
举个例子,他们做的事情几乎是一样的。 但是,假设您想同时解决三件事情(想象一下同时需要AJAX提供三种资源),并在三件事完成时继续。 承诺是微不足道的,因为基本上没有什么变化。 但通过回调,你需要设置一些标志/计数器,并且自己识别成功和失败状态 - 更多的工作。
在语义上,两段代码之间确实没有真正的区别。 消息在调用初始函数后的某个时间提供给回调函数。
从设计的角度来看,人们倾向于赞成承诺,因为他们通常会更容易遵循代码。 在回调处理某些长时间运行的函数的结果时,尤其如此。 考虑以下两个运行缓慢的功能:
var slowlyReturn1 = function (callback) {
window.setTimeout(callback.call(1), 1000);
}
var slowlyReturn2 = function (callback) {
window.setTimeout(callback.call(2), 1000);
}
编写使用这两个长时间运行函数结果的代码非常有趣:
slowlyReturn1(function(resultOf1) {
slowlyReturn2(function(resultOf2) {
console.log("results were: " + resultOf1 + " and " + resultOf2);
})
});
注意长连续函数链中的每个链接如何导致另一个嵌套级别。 使用承诺代码,您通常不会遇到此问题:
var slowlyReturn1 = function () {
var d = $.Deferred();
window.setTimeout(function () { d.resolve(1) }, 1000);
return d.promise();
}
var slowlyReturn2 = function () {
var d = $.Deferred();
window.setTimeout(function () { d.resolve(2) }, 1000);
return d.promise();
}
var resultOf1;
slowlyReturn1().then(function(r) {
resultOf1 = resultOf1;
return slowlyReturn2();
}).then(function(resultOf2) {
console.log("results were: " + resultOf1 + " and " + r);
});
此外,使用承诺代码,往往会出现更清晰的问题分离。 执行慢速运行操作的代码不知道结果将如何使用:它只是返回表示延迟结果并让调用方处理它的内容。
你处理它的一个很好的应用就是围绕异常处理。 缓慢运行的操作可能会.resolve()
承诺,但他们也可能.reject()
出现问题。 这种拒绝可以使用.fail()
来处理,如下所示:
slowRunningOperations().then(function () {
...
...
... handle success
...
...
}).fail(function() {
...
... handle failure
...
...
})
在这里,慢速运行的调用者不关心错误,它可以简单地忽略它们。
承诺编程还有其他几个好处:
大多数支持promise的库提供了一种方法来处理普通函数和函数,它们以相同的方式返回promise。 他们通常通过提供一个叫做when()
的函数来实现这一点。 这为测试承诺代码提供了一个非常好的方法,或者允许将慢速函数更改为影响调用者的promise-returning-one w / o。
大多数支持promise的库也提供了使用promise来模拟更传统控制流的功能。 例如,Q库提供了allSettled(list)
,它接受一个promise的列表并返回一个promise,该promise在列表中的所有promise都完成时解析。
也就是说,正如另一个答案所述,承诺会带来一些开销。 如果你没有进行强化链接或错误处理,或者严格按照控制流使用回调,那么只需传递函数即可。
链接地址: http://www.djcxy.com/p/55441.html上一篇: Callback or Promise?