美文网首页
一道JavaScript面试题, 考察多种回调写法

一道JavaScript面试题, 考察多种回调写法

作者: HiLeo | 来源:发表于2016-05-22 17:44 被阅读292次

    题目:红灯三秒亮一次,绿灯两秒亮一次,黄灯一秒亮一次;如何让三个灯不断交替重复亮灯?三个亮灯函数已经存在:

    function red(){
        console.log('red    - ', new Date());
    }
    
    function green(){
        console.log('green  - ', new Date());
    }
    
    function yellow(){
        console.log('yellow - ', new Date());
    }
    

    1. callback实现

    function loop(){
        setTimeout(function(){
            red();
            setTimeout(function(){
                green();
                setTimeout(function(){
                    yellow();
                    loop();
                }, 1000)
            }, 2000)
        }, 3000);
    }
    loop();
    

    2. Promise实现

    返回Promise对象的通用亮灯函数

    function tic(timer, callback){
        return new Promise(function(resolve, reject){
            setTimeout(function(){
                callback();
                resolve();
            }, timer)
        })
    }
    
    var promise = new Promise(function(resolve, reject){ resolve() });
    function loop(){
        promise.then(function(){
            return tic(3000, red);
        }).then(function(){
            return tic(2000, green);
        }).then(function(){
            return tic(1000, yellow);
        }).then(function(){
            loop();
        })
    }
    loop();
    

    3. Generator实现

    function* light(){
        yield tic(3000, red);
        yield tic(2000, green);
        yield tic(1000, yellow);
    }
    
    function loop(iterator, gen){
        var result = iterator.next();
        if (result.done) {
            loop(gen(), gen)
        } else {
            result.value.then(function(){
                loop(iterator, gen)
            })
        }
    };
    
    loop(light(), light);
    

    4. async, await实现

    (async function (){
        while(true){
            await tic(3000, red);
            await tic(2000, green);
            await tic(1000, yellow);
        }
    })();
    

    5. 改进版的可扩展callback实现

    function light(func, timer){
        return function(callback){
            setTimeout(function(){
                func();
                callback();
            }, timer)
        };
    }
    
    function queue(funcs){
        (function next(){
            if (funcs.length > 0){
                var f = funcs.shift();
                f(next)
            }
        })();
    }
    
    function loop(){
        queue([
            light(red, 3000),
            light(green, 2000),
            light(yellow, 1000),
            loop
        ])
    }
    loop();
    

    总结

    1. 最简单的callback实现,当有更多个函数时,会导致回调地狱,代码惨不忍睹,但经过封装后,也可进行方便的扩展。
    2. Promise实现中规中矩
    3. Generator实现中包含了一个通用的Generator顺序执行函数
    4. 最爱async, await实现

    引用

    相关文章

      网友评论

          本文标题:一道JavaScript面试题, 考察多种回调写法

          本文链接:https://www.haomeiwen.com/subject/ddnorttx.html