【问题标题】:What design pattern is jQuery's Deferreds and Promises?jQuery Deferred 和 Promises 是什么设计模式?
【发布时间】:2014-04-12 15:35:03
【问题描述】:

貌似jQuery的Deferred其实可以处理一个Deferred对象和Promise对象能做的所有方法,但是它只返回一个Promise对象给用户,这样就给出了方法的一个子集,这样用户就无法解析或者拒绝——拒绝用户不应该做的事情。

所以 Deferred 作为一个类实际上是相当清楚的。令人困惑的是另一个类 Promise,它使事情看起来更复杂,因为现在这种模式有两个类,它可能看起来令人困惑。

不知道

  1. 以上准确吗?
  2. 它是它自己的设计模式,还是它实际上类似于其他经典设计模式,实际上有这种“许多方法”是可能的(延迟)但“只限制它的一个子集提供给class" (Promises) 类型的设计模式?

【问题讨论】:

  • 设计模式?这只是对象!
  • 我认为设计模式的全部内容是关于对象的常见使用模式
  • 可能,我真的不知道?
  • 也许是旁观者。该术语包含 designpattern 词,因此通常是基于意见的。
  • 其实,它看起来确实像观察者模式...通知观察者,在特定情况下,例如条形图和饼图都观察数据,当数据发生变化时,通知观察者观察者(图表),只是这一次,它就像一个“延迟的结果,当结果到达时,通知观察者”。所以数据“有一个”观察者注册对象,就像一个延迟的“有一个”观察者注册对象(这是承诺)。

标签: jquery design-patterns promise jquery-deferred


【解决方案1】:
  1. 正如您所说,Promise 公开了 Deferred 接口的子集。 Promise 应该用于附加成功/失败/进度事件。

  2. 是的,Deferreds/Promises 是它自己的一种设计模式。而且实际上非常重要。

【讨论】:

    【解决方案2】:

    上面说的对吗?

    是的。你可以说jQuery.Deferred 是jQuery Promise 的子类。

    它是自己的设计模式吗

    可能,但选择不当。 Deferreds 和 Promises 应该 如何作为两个独立的接口工作 - 你要么拥有可以解决问题的对象或者你拥有可以解决的对象(你可以observe)。 deferred 甚至可以被视为承诺的builder

    【讨论】:

    • 所以 Deferred 继承自 Promise... 和 d.__proto__ === p.constructor.prototype,如 jsfiddle.net/4e8b4
    • 不,我的意思是“类”的“继承模式”。这里没有涉及原型继承,它是一个简单的 mixin。见theselines来源
    • 你的意思是像经典继承吗? jsfiddle 所显示的是它从延迟到承诺沿着原型链上升,它可以是经典的或原型的......无论如何,JS 使用原型实现经典——这就是你的意思吗?经典继承?
    • 你的小提琴什么都没有显示 - p.constructor === Object,延迟和承诺都只是(原型)从Object.prototype继承的普通对象。我不是指经典的原型继承,我指的是作为模式的“类”。这里是用 mixins 实现的。
    • hm,我想我在那里犯了一个错误,如果 foo 从经典或原型继承 bar 的类,它真的应该是 foo.__proto__.__proto__ === bar.constructor.prototype
    【解决方案3】:

    jQuery 的 Promise 部分受现有技术的影响,包括 Q Promise 和 Dojo 和 Twisted Python deferreds,而后者又受到 E 中的 Promise 的启发。在 E 和随后的 Q 中,promise 和解析器是基于对象能力的独立对象编程(OCap)设计原则。在 Q 中,promiseresolve 是独立的能力承载对象,“deferred”只是这些能力的容器。在 ES6 Promise 设计中,deferred 存在但在接口中不存在以消除混淆——相反,promise 构造函数接受一个回调,resolve 作为参数发送到该回调。

    E 专为面向对象的安全性和多进程中代理的健壮组合而设计。 Promise 是确保 E 的所有目标的重要原语。对象能力范式是访问控制列表范式的替代方案。取代面向用户的权限,功能被分解为单独的对象。授予权限就像让代理访问具有能力的对象一样简单,而 OCap 依赖于一个环境,在该环境中,可以保证只能通过与其他对象的显式和故意交互来获得能力。使用弱映射创建的对象膜(以确保内存不会泄漏)和代理(以创建始终包装跨膜引用并且以后可以破坏的边界)也可以撤销权限。

    观察和通知是独立的功能。可以赋予一些代理观察承诺解决的权力,并赋予其他代理解决承诺的能力。在安全系统中,通信通道是单向的很重要。一个解析器可以将一个值传达给所有观察者,但任何观察者或解析器都不能以其他方式干扰任何其他代理的不变量。

    Promises 是 Gamma et Al Observer 模式或 Publisher, Subscriber 模式的变体。还有值得注意的额外限制。 Promise 是一个广播发布者。可以通知多个观察者。 Promise 还保证只有一个解决方案,要么解决,要么拒绝。与 PubSub 不同,promise 将通知观察者,无论它是在发送一个决议之前还是之后开始观察。与 Event Emitter 不同,promise 保证异步。事件发射器通常在 DOM 和 Node.js 中是同步的。

    出于稳健组合安全性的目的,promise 保证所有处理程序都将在单独的事件中被调用。这可以防止函数以多种方式干扰共享同一调用堆栈的其他实体,例如调用关闭状态的函数,该状态不一定在函数返回之前设置,或者检查自己的堆栈以推断其他代理正在做。

    大多数 JavaScript 环境都不足以满足 Promise 设计的安全保证。 Google Caja 和 DrSES 就是创建此类环境的项目。然而,Q Promise 被设计为与原始设计兼容,这样为 Q 用户编写的代码可以更容易地移植到这样的环境中。出于同样的原因,与其他 JavaScript 承诺库不同,Q 也像 E 承诺一样设计,基于消息传递“内核”,允许它们用于向其他进程中的对象发送消息,返回结果的承诺,这可以是用作向结果发送更多消息的代理。

    jQuery 采用了 Promise,但只是部分欣赏了现有技术。 jQuery 中的 promise 围绕 jQuery 自己的事件调度模式进行了重新评估,默认情况下具有多个输入和输出,这打破了 promise 对应于函数调用的结果(返回值或抛出的异常)的类比。 jQuery Promise 也不会捕获异常,因此如果应通知观察者失败,则有必要显式创建“拒绝”。这使得某些代理无法从某些错误中恢复。 jQuery 还决定效仿 Dojo 和 Twisted 将 Promise 和 resolver 合并为一个对象,旨在使界面更易于使用。 jQuery Promise 最初并没有为已完成或被拒绝的处理程序的返回值创建新的 Promise,但后来纠正了这个错误。

    【讨论】:

      猜你喜欢
      • 2013-09-28
      • 2012-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多