jQuery延迟/承诺设计模式和使用案例

5

我的问题很普遍,一些相关的问题可以在SO上找到,但没有一个真正符合我所寻找的。

我一直在研究和玩弄jQuery Deferred对象,我发现它在库本身内部被广泛用于处理ajax请求和动画等。我理解其一般功能,并认为在某些情况下它已经被证明非常有用。 jQuery库使用这个概念非常优雅地解决了一些问题。

现在我的问题是:我认为拥有一份可以通过使用Deferred对象来解决不同问题/解决方案场景的概述将非常有用且稳健。

在哪些情况下需要使用jQuery Deferred的解决方案?可以区分出哪些javascript软件设计中的通用模式,可以通过使用jQuery Deferred功能来最优雅地解决? 我的目标是编制一个相当通用模式的列表(与非常具体的示例相对),以OO分析师都知道的Gang of Four设计模式的精神为指导。

有了这样一个列表,当设计jQuery解决方案时,应该变得轻而易举地利用这些延迟模式,就像桥梁、工厂等模式已经帮助我们设计灵活和稳健的解决方案一样,而不必每次都重新发明轮子。


如果这个问题没有因为过于宽泛而被关闭,您应该将其标记为“社区维基”。 - Alnitak
我该如何将它标记为社区维基? - Asciiom
如果您编辑问题,它应该显示为复选框。 - Alnitak
嗯,好像不行,也许是我声望不够。有人能帮我做一下吗? - Asciiom
2个回答

6

异步任务大致可以分为5个不同的问题领域。

网络/本地数据请求

这可能是最常见的领域,也是Fabrizio Calderan的回答所涵盖的。在这些情况下,我们必须处理至少两个结果,并根据细粒度(请求的各种成功或错误类型)采取行动。

Deferred/Promises 可以让我们链接或并行请求,或者二者混合以实现我们任务所需的资源加载。例如,我们可以等待一系列请求完成后,再加载更多内容,或者根据这些结果执行其他操作。

动画

链式/并行动画序列更易于实现和维护。基于不同结果的条件步骤(当考虑用户交互或随机因素时)也很容易实现和维护。

(伪)模态用户交互

在浏览器中无法进行真正的模态操作,而呈现对话框、向导等需要异步操作提供的 Deferred/Promises 来在清理显示(如上所述)并恢复正常操作之前对已解决的结果(成功、活动、选项、取消等)进行操作。Deferred/Promises 允许您以相对简单的声明方式对这些结果进行操作。

实际上,这将用户交互与动画/显示序列结合起来。

硬件可用性/响应

在调用移动设备(例如通过 PhoneGap)提供的服务之前,需要确保其可用性,并且在许多情况下,以异步方式提供响应。使用 Deferred/Promises 简化和改进了管理这些设备交互的代码。

软件组件活动

SQLLite 特别提供其响应用于 JS 异步请求,因此进行复杂的查询交互比使用回调要简单得多。

理论上,这适用于任何提供异步响应的辅助软件组件。

还有一件事...

这是我阅读过的关于 Deferred/Promises 的最好文章之一,我建议阅读它以获取一些具有深度的示例和解释。

总而言之

Deferred/Promises 的巨大优势在于它们使得在第一时间内构思并维护几个领域的解决方案变得更加容易。在某些情况下,它们简化了这些解决方案,以致如果试图使用回调和复杂的结果检查来尝试实现它们,则会让很多成年人(可能还有一些小孩子)感到困扰。

...将从这里开始...

我们乘船而行,并使用 Deferred/Promises

...到达这里。

回调函数是一场噩梦

如果解决方案需要链接多个进程的结果,等待一个或多个进程的结果解析,或者任何这些的组合,Deferred/Promises将为您节省沮丧和痛苦,并为继承您代码的任何人做同样的事情。

现在,通过犯下可怕的滥用来证明我是错的。不要这样做。编写漂亮干净、易于维护的代码。

免责声明:在您的代码中使用Deferred/Promises可能不会让您感觉像“坐在船上”,但它比回调函数做的更好。


4
在哪些情况下需要使用jQuery Deferred解决方案?
我认为,作为一个经验法则,每当你有以下两种情况时:
1. 一个或多个异步任务 2. 一些相关的回调依赖于这些任务的成功/失败
你可以尝试使用deferred对象和promises来重构你的代码。最常见的使用deferred对象的场景包括:
- Ajax请求和回调(单个请求、并行或链接请求) - 资产的异步加载和在load事件上执行的操作(例如像这样的图像预加载器:https://gist.github.com/958683) - 在动画完成后执行回调或需要大量嵌套范围的顺序动画:只需将promise()方法链接到animate()方法,以返回一个promise来处理done()回调即可轻松实现此目标(说实话,我真的无法想象动画如何失败)
希望这个提示对你有所帮助。

好的开始!希望这个列表会随着时间的推移而增长。 - Asciiom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接