Rev*_*ous 35 javascript jquery callback promise
你能解释一下下面的短语(取自Stack Overflow问题的答案,在Javascript中Deferred,Promise和Future之间有什么区别?)?
使用jQuery promises反对使用以前的jQuery回调有什么优点?
不是直接将回调传递给函数,而是使用promises可以导致紧密耦合的接口,而是可以分离对同步或异步代码的关注.
Rui*_*Rui 49
promise是一个表示异步操作结果的对象,因此可以传递它,这样可以提供更大的灵活性.
如果使用回调,则在调用异步操作时必须指定如何处理它,从而指定耦合.有了承诺,您可以指定以后如何处理.
这是一个例子,想象你想通过ajax加载一些数据,同时你想要显示一个加载页面.
void loadData = function(){
showLoadingScreen();
$.ajax("http://someurl.com", {
complete: function(data){
hideLoadingScreen();
//do something with the data
}
});
};
Run Code Online (Sandbox Code Playgroud)
处理返回数据的回调必须调用hideLoadingScreen.
使用promises,您可以重写上面的代码段,使其更具可读性,并且您不必将hideLoadingScreen放在完整的回调中.
var getData = function(){
showLoadingScreen();
return $.ajax("http://someurl.com").promise().always(hideLoadingScreen);
};
var loadData = function(){
var gettingData = getData();
gettingData.done(doSomethingWithTheData);
}
var doSomethingWithTheData = function(data){
//do something with data
};
Run Code Online (Sandbox Code Playgroud)
更新:我写了一篇博文,提供了额外的例子,并提供了一个明确的描述,即什么是一个承诺,以及如何将其使用与使用回调进行比较.
har*_*rpo 27
耦合对承诺更宽松,因为操作不必"知道"它是如何继续的,它只需知道它何时准备就绪.
当您使用回调时,异步操作实际上引用了它的继续,这不是它的业务.
使用promises,您可以在决定如何解决之前,轻松地在异步操作上创建表达式.
因此,承诺有助于将链接事件与实际工作的关注分开.
Olm*_*lmo 12
我不认为承诺比回调更多或更少耦合,几乎相同.
然而,承诺还有其他好处:
如果你公开一个回调,你必须记录它是否会被调用一次(比如在jQuery.ajax中)或者不止一次(比如在Array.map中).承诺总是被召唤一次.
没有办法在其上调用回调抛出和异常,因此您必须为错误情况提供另一个回调.
只需要注册一个回调,不止一个回复,你可以在事件发生后注册它们,无论如何你都会被调用.
在类型化声明(Typescript)中,Promise使签名更容易阅读.
将来,您可以利用async/yield语法.
因为它们是标准的,所以你可以制作像这样的可重用组件:
disableScreen<T>(promiseGenerator: () => Promise<T>) : Promise<T>
{
//create transparent div
return promiseGenerator.then(val=>
{
//remove transparent div
return val;
}, error=>{
//remove transparent div
throw error;
});
}
disableScreen(()=>$.ajax(....));
Run Code Online (Sandbox Code Playgroud)更多内容:http://www.html5rocks.com/en/tutorials/es6/promises/
编辑:
此外,虽然我仍然认为这不是主要观点,但现在我认为它们因为这个原因而松散耦合:
它们是标准的(或者至少是尝试):使用字符串的C#或Java中的代码比C++中的类似代码更糟糕,因为字符串的不同实现使其更具可重用性.有一个标准的承诺,调用者和实现彼此之间的耦合较少,因为他们不必同意自定义参数命令,名称等的(一对)自定义回调...事实上有很多不同承诺的味道无济于事.
它们促进了更多基于表达式的编程,更容易编写,缓存等.:
var cache: { [key: string] : Promise<any> };
function getData(key: string): Promise<any> {
return cache[key] || (cache[key] = getFromServer(key));
}
Run Code Online (Sandbox Code Playgroud)你可以说基于表达式的编程比基于命令/回调的编程更松散地耦合,或者至少它们追求相同的目标:可组合性.
Promise将延迟响应的概念归结为某种东西.他们使异步计算成为一流的公民,因为你可以传递它.它们允许您根据需要定义结构 - 一元结构 - 您可以在其上构建更高阶的组合器,从而大大简化代码.
例如,你可以有一个函数,它接受一个promises数组并返回一个数组的promise(通常叫做sequence).回调很难做甚至不可能.而这样的组合器不仅使代码更容易编写,而且使它更易于阅读.
现在考虑另一种方式来回答你的问题.回调是一种特殊的解决方案,承诺允许更清晰的结构和可重用性.