Raymond巍达

导航

 

何为回调函数

1 setTimeout(function () {
2   console.log('callback...');
3 }, 1000);

此延时定时器中的function就是我们常说的回调函数,回调函数常常满足三个特征

  • 我们自己定义的
  • 我们自己没去执行
  • 最终被其它人(浏览器的ajax模块,定时器模块...)执行了

 

何为回调地狱

 1 setTimeout(function (name) {
 2   var catList = name + ',';
 3 
 4   setTimeout(function (name) {
 5     catList += name + ',';
 6 
 7     setTimeout(function (name) {
 8       catList += name + ',';
 9 
10       setTimeout(function (name) {
11         catList += name + ',';
12 
13         setTimeout(function (name) {
14           catList += name;
15 
16           console.log(catList);
17 
18         }, 1, 'Lion');
19 
20       }, 1, 'Snow Leopard');
21 
22     }, 1, 'Lynx');
23 
24   }, 1, 'Jaguar');}, 1, 'Panther');

由于回调函数是异步的,在上面的代码中每一层的回调函数都需要依赖上一层的回调执行完,所以形成了层层嵌套的关系最终形成类似上面的回调地狱,但代码以此种形式展现时无疑是不利于我们阅读与维护的,此时就要想办法改进这种代码形式。

 

初次改进

    var catList = '';

    setTimeout(getPanther, 1, 'Panther');

    function getPanther(name) {
        catList += name + ',';
        setTimeout(getJanguar, 1, 'Janguar');
    }

    function getJanguar(name) {
        catList += name + ',';
        setTimeout(getLynx, 1, 'Lynx');
    }

    function getLynx(name) {
        catList += name + ',';
        setTimeout(getSnowLeopard, 1, 'Snow Leopard');
    }

    function getSnowLeopard(name) {
        catList += name + ',';
        setTimeout(getLion, 1, 'Lion');
    }

    function getLion(name) {
        catList += name;
        setTimeout(print, 1);
    }

    function print() {
        console.log(catList);
    }

将匿名函数命名

虽然匿名函数使用方便,但是不利于我们阅读与书写,所以我们选择将回调函数单独的拿出来并命名,写成如上形式,这样看上去就要比第一次的代码优雅清晰很多。需要注意的是上面的代码相比之前有了几点改变。

1. catList变成了全局变量

2. 函数的作用域发生了变化,从局部作用域变成了全局作用域,所以才需要将catList变成全局变量以保证每个函数都可以访问的到

通常情况下我们不希望有全局变量污染环境,并且上面的代码还有一些可以复用的空间,可以看到我们在每个函数中都重复的调用定时器,所以我们可以再来改进一下上面的代码。

 

再次改进

 

 1     function buildCatList(list, returnVal, fn) {
 2         setTimeout(function (name) {
 3             var catList = list === '' ? name : list + ',' + name;
 4             fn(catList);
 5         }, 1, returnVal);
 6     }
 7 
 8 
 9     buildCatList('', 'Panther', getJanguar);
10 
11     function getJanguar(list) {
12         buildCatList(list, 'Janguar', getLynx);
13     }
14 
15     function getLynx(list) {
16         buildCatList(list, 'Lynx', getSnowLeopard);
17     }
18 
19     function getSnowLeopard(list) {
20         buildCatList(list, 'Snow Leopard', getLion);
21     }
22 
23     function getLion(list) {
24         buildCatList(list, 'Lion',print);
25     }
26 
27     function print(list) {
28         console.log(list);
29     }

 

定时器中的回调函数处在外层函数中的作用域内,并通过参数传入,没有产生全局变量,没有重复代码。

 

posted on 2016-10-26 13:22  Raymond巍达  阅读(10510)  评论(0编辑  收藏  举报