5-3 认识$.Deferred的接口
本节编程练习不计算学习进度,请电脑登录imooc.com操作

认识$.Deferred的接口

大多情况下,promise作为一个模型,提供了一个在软件工程中描述延时(或将来)概念的解决方案。它背后的思想我们已经介绍过:

不是执行一个方法,然后阻塞应用程序等待结果返回,而是返回一个promise对象来满足未来值。

这样看来,Promise/A只是一种规范,Deferred可以看作这种规范的具体实现,旨在提供通用的接口,用来简化异步编程难度,说白了就是:

一个可链式操作的对象,提供多个回调函数的注册,以及回调列队的回调,并转达任何异步操作成功或失败的消息。

jQuery.Deferred()背后的设计理念来自 CommonJS Promises/A , jQuery.Deferred()基于这个理念实现,但并没有完全遵循其设计, 它代表了一种可能会长时间运行而且不一定必须完整的操作的结果,简单的描述下规范中定义的“Promise”。

promise模式在任何时刻都处于以下三种状态之一:

未完成(unfulfilled)
已完成(resolved)
拒绝(rejected)

CommonJS Promise/A 标准这样定义的,promise对象上的then方法负责添加针对已完成和拒绝状态下的处理函数。then方法会返回另一个promise对象,这样可以形成“管道”风格。

看看jQuery的Deferred源码中对动作接口的定义:

[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
[ "notify", "progress", jQuery.Callbacks("memory") ]

Deferred中定义的动作是非常多的,抽象的看其实可以类似一种观察者模式的实现。

观察者模式中的订阅方法:

  Done (操作完成)
  Fail (操作失败)
  Progress (操作进行中

观察中模式中的发布方法:

  resolve(解决)
  reject(拒绝)
  notify(通知)

而且还提供了可以定义运行时的this对象的fire,fireWith,所以扩展了3个可以定义上下文的的接口:

  resolveWith
  rejectWith
  notifyWith

所以按照这样的规范,我们的使用就应该是这样:见右边代码。

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://code.jquery.com/jquery-latest.js"></script>
  6. <title></title>
  7. </head>
  8. <body>
  9. <button id="aaron1">例一:基本用法</button>
  10. <button id="aaron2">例二:过滤器</button>
  11. <button id="aaron3">例三:promise方法</button>
  12. <script type="text/javascript">
  13.  
  14. //例一
  15. $("#aaron1").on("click", function() {
  16. // 构建一个deferred对象
  17. var dtd = $.Deferred();
  18. // 给deferred注册一个成功后的回调通知
  19. dtd.done(function() {
  20. show('成功')
  21. })
  22. // 开始执行一段代码
  23. setTimeout(function() {
  24. dtd.resolve(); // 改变deferred对象的执行状态
  25. }, 2000);
  26. })
  27.  
  28.  
  29. //例二:过滤器
  30. var filterResolve = function() {
  31. var defer = $.Deferred(),
  32. filtered = defer.then(function(value) {
  33. return value * 2;
  34. });
  35. defer.resolve(5);
  36. filtered.done(function(value) {
  37. show("Value is ( 2*5 = ) 10: " + value);
  38. });
  39. };
  40. $("#aaron2").on("click", filterResolve)
  41.  
  42.  
  43. //例三:实现promise方法
  44. $("#aaron3").on("click", function() {
  45. var obj = {
  46. hello: function(name) {
  47. show("你好 " + name);
  48. }
  49. },
  50. defer = $.Deferred();
  51. // 设置一个promise
  52. defer.promise(obj);
  53. //解决一个deferred
  54. defer.resolve("慕课网");
  55. obj.done(function(name) {
  56. obj.hello(name);
  57. }).hello("Aaron");
  58. })
  59.  
  60.  
  61. function show(data) {
  62. $("body").append('<li>' + data + '</li>')
  63. }
  64.  
  65.  
  66. </script>
  67.  
  68. </body>
  69. </html>
下一节