日期:2014-05-16  浏览次数:20436 次

JavaScript 中的异步梳理(1)——使用消息驱动

继续上一篇文章,这篇探讨使用消息驱动来优化异步编程体验。

先举一个例子,如果希望 ABCDE 这 5 个函数依次执行,我们可以写出如下代码。

A();
B();
C();
D();
E();

在同步的情况下,这样的代码没有任何问题。 但如果 ABCDE 都是异步的,还需要按次序执行,这样写就不行了。 通常我们会为异步函数设置回调,当函数执行完的时候执行回调,例如

A(function(){
    B(function(){
        C(function(){
            D(function(){
                E();
            });
        });
    });
});

毫无疑问这样的编程体验是很差的。 当异步流复杂的时候回调嵌套层数会很多,完全就是一场噩梦。

这还不是最重要的,如果想表达「当 AB 都完成的时候执行 C」这样的流程,并且希望 A/B 可以并行,就不能简单的用这样的回调了。 虽然说「当 AB 都完成的时候执行 C」可以通过设置一个布尔量来解决, 但是「当 ABCD 都完成的时候执行 E」这样的逻辑就需要在每个函数执行完的时候去判断其他函数是否执行完,虽然的确是可行的,但是编程体现是比较差的。

身为一名懒惰的程序员,这样显然满足不了我们的胃口。

@朴灵?写了一个?EventProxy,提供了事件驱动的异步编程体验

var proxy = new EventProxy();
proxy.assign('A', function(){
    B(function(){
        proxy.trigger('B');
    });
});
proxy.assign('B', function(){
    C(function(){
        proxy.trigger('C');
    });
});
proxy.assign('C', function(){
    D(function(){
        proxy.trigger('D');
    });
});
proxy.assign('D', function(){
    E();
});
A(function(){
    proxy.trigger('A');
});

可以看出通过消息来驱动代码可以让异步嵌套被「拉平」了,而如果要描述「当 ABCD 都完成的时候执行 E」这样的流程也很容易了

var proxy = new EventProxy();
proxy.assign('A', 'B', 'C', 'D', E);
A(function(){
    proxy.trigger('A');
});
B(function(){
    proxy.trigger('B');
});
C(function(){
    proxy.trigger('C');
});
D(function(){
    proxy.trigger('D');
});

除了改善异步编程体验以外,EventProxy 也可以提供一个自定义的事件系统。

EventProxy 很简单,源代码只有 300 多行,但是对于我这样的移动开发者来说任何用不上的代码都是负担。