似乎jQuery的Deferred实际上可以处理Deferred对象和Promise对象可以执行的所有方法,但它只向用户返回一个Promise对象,以便给出方法的子集,以便用户无法解析或拒绝 - 用户不应该做的事情。
因此,Deferred实际上非常清楚。可能令人困惑的是另一个类Promise,它使事情看起来更复杂,因为现在这个模式有两个类,它可能看起来很混乱。
我想知道
答案 0 :(得分:10)
jQuery的承诺部分地受到现有技术的启发,包括Q promises和Dojo以及Twisted Python延迟,后者又受到E中的承诺的启发。在E和随后的Q中,承诺和解析器是基于对象能力的单独对象编程(OCap)设计原理。在Q中,promise
和resolve
是单独的能力承载对象,“延迟”只是这些功能的容器。在ES6 Promise
设计中,延迟存在,但是在接口中不存在以消除混淆 - 相反,promise构造函数接受将resolve
作为参数发送的回调。
E专为面向对象的安全性和多个流程中代理的强大组合而设计。承诺是确保所有E目标的重要原则。对象能力范例是访问控制列表范例的替代方案。功能不是面向用户的权限,而是分解为单个对象。授予权限就像让代理访问具有功能的对象一样简单,而OCap依赖于一个环境,在该环境中可以保证只有通过与其他对象的明确和有意的交互才能获得功能。使用弱映射创建的对象膜(以确保内存不会泄漏)和代理(创建跨膜引用总是被包裹并且可以在以后被破坏的边界)也可以撤销权限。
观察和通知是单独的功能。有可能让某些代理人有权观察承诺的解决,并让其他代理人有能力解决承诺。在安全系统中,通信信道是单向的是重要的。一个解析器可以将一个值传递给所有观察者,但是没有观察者或解析器能够以其他方式干扰任何其他代理的不变量。
Promise是Gamma et Al Observer模式或Publisher,Subscriber模式的变体。还有值得注意的附加限制。承诺是广播发布者。可以通知多个观察者。 Promise还保证一个解决方案,无论是解决还是拒绝。与PubSub不同,承诺将通知观察者,无论它是在调度一个分辨率之前还是之后开始观察。与事件发射器不同,承诺保证不同步。事件发射器通常在DOM和Node.js中是同步的。
出于健壮的组合和安全性的目的,promise保证在单独的事件中调用所有处理程序。这可以防止函数以多种方式干扰共享同一调用堆栈的其他实体,例如调用在函数返回之前未必设置的状态关闭的函数,或者检查自己的堆栈以推断其他代理正在做。
大多数JavaScript环境不足以满足promise设计的安全保证。 Google Caja和DrSES是创建此类环境的项目。但是,Q promises旨在与原始设计兼容,以便为Q用户编写的代码可以更轻松地移植到这样的环境中。出于同样的原因,与其他JavaScript承诺库不同,Q也被设计为基于传递“内核”的消息的E promises,允许它们用于向其他进程中的对象发送消息,返回可能的结果的promise。用作代理以获取结果的更多消息。
jQuery采用了承诺,但只是部分地赞赏了现有技术。 jQuery中的promise是围绕jQuery自己的事件调度模式重新评估的,默认情况下有多个输入和输出,这打破了promise对应于函数调用结果的类比,无论是返回值还是抛出异常。 jQuery promises也不捕获异常,因此如果观察者应该被告知失败,就必须明确地创建“拒绝”。这使得某些代理无法从某些错误中恢复。 jQuery还决定跟随Dojo和Twisted将promise和resolver合并为一个对象,旨在使界面更易于使用。 jQuery promises最初没有为履行或拒绝的处理程序的返回值创建新的承诺,但后来纠正了这个错误。
答案 1 :(得分:1)
是上述准确吗?
是。你可以说jQuery.Deferred
是jQuery Promise
的子类。
它是自己的设计模式
可能,但是选择不当。延迟和承诺应该如何工作是两个独立的接口 - 你要么拥有可以解析事物的对象或你有得到解决的对象(你可以observe)。延迟甚至可以被视为承诺的builder。
答案 2 :(得分:0)
Promise公开了Deferred接口的子集,正如您所说的那样。承诺应该用于附加成功/失败/进展事件。
是的,Deferreds / Promises是一种自己的设计模式。实际上非常重要。