3-8 once的设计
本节编程练习不计算学习进度,请电脑登录imooc.com操作

once的设计

这一小节我们来讲一下once。

once的作用确保回调列表只执行(.fire())一次(像一个递延 Deferred),如下代码:

function fn1(val){
    console.log('fn1 says ' + val);
}
var cbs = $.Callbacks('once');
cbs.add(fn1);
cbs.fire('foo');
cbs.fire('foo');

结果你会发现cbs.fire('foo')只执行了一次。

fn1 says foo  //只显示一次

once定义是很明确的,确保这个回调列表只执行( .fire() )一次(像一个递延 Deferred),所以针对这种once的处理可以有多种不同的途径实现。

1、add的时候抛弃

2、在fire的时候抛弃多个。

但是jQuery是在执行第一个fire的时候直接给清空list列表了,然后在add的地方给判断下list是否存在,从而达到这样的处理。

function Callbacks(options) {
  var list = [];
  var self;
  self = {
    add: function(fn) {
      list.push(fn)
    },
    fire: function(args) {
      if (list) {
        list.forEach(function(fn) {
          fn(args);
        })
        if (options === 'once') {
          list = undefined;
        }
      }
    }
  }
  return self;
}

在fire之后,判断参数是否为once,直接把list给清理掉,所以之后的所有fire都被抛弃掉了,而从达到了once的效果。

jQuery.Callbacks的处理

在fire中调用了 self.disable(); 方法

// 禁用回调列表中的回调。
disable: function() {
    list = stack = memory = undefined;
    return this;
},

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://img1.sycdn.imooc.com//down/540812440001e40e00000000.js" type="text/javascript"></script>
  6. <script src="http://img1.sycdn.imooc.com//down/541f6ff70001a0a500000000.js" type="text/javascript"></script>
  7.  
  8. <title></title>
  9. </head>
  10. <body>
  11.  
  12. <script type="text/javascript">
  13.  
  14.  
  15. function Callbacks(options) {
  16. var list = [];
  17. var self;
  18. self = {
  19. add: function(fn) {
  20. list.push(fn)
  21. },
  22. fire: function(args) {
  23. if(list){
  24. list.forEach(function(fn) {
  25. fn(args);
  26. })
  27. if(options === 'once'){
  28. list = undefined;
  29. }
  30. }
  31. }
  32. }
  33. return self;
  34. }
  35.  
  36.  
  37. function fn1(val) {
  38. show('fn1 says:' + val);
  39. }
  40. function fn2(val) {
  41. show('fn2 says ' + val);
  42. }
  43.  
  44.  
  45. var cbs = Callbacks('once');
  46. cbs.add(fn1);
  47. cbs.fire('foo');
  48. cbs.fire('foo');
  49.  
  50.  
  51. </script>
  52.  
  53. </body>
  54. </html>
下一节