« Home

edit

blendjs的异步加载

项目地址:http://github.com/towry/blendjs

这个是昨天下午写的东西,用于异步定义模块。所谓异步定义模块就是,可以不用考虑模块的顺序,进行模块定义。一般来说,如果模块A依赖于模块B,那么B是必须是出现于模块A前面的。但是使用异步技术,可以使模块A的定义延迟于模块B。这好样类似于promise了。

昨天写完blendjs后,今天想到了一个问题,那就是如果某个模块没有被定义,依赖它的模块会不会有什么问题呢。我测试了一下,发现如果有个被依赖的模块没有定义,那么依赖者不会被运行,没有任何错误发生(前提是你写的代码没语法错误)。没有错误发生,这也算是一个没有错误的错误了!!

如果模块A依赖于模块B,比如:

define('A', ['B'], function (b) {
   console.log(b);
});

这时没有任何错误。但是我们应该抛出一个异常,比如“模块B未被定义”。好让使用者知道,代码没什么错误也不运行,是因为某个模块未被定义。

那么怎么解决这个问题呢?blendjs有个“pending”变量,这个变量保存的是未被定义的模块,这些模块都被其他的模块所依赖。所以,我们要在代码结束后,检查这个pending变量,如果这个变量还有东西,那就说明有被依赖的模块未被定义,就抛出异常。而要做这个检查,就要在最后一个define函数调用后进行检查。但是怎么知道某个define的调用是最后一次调用呢?

define('a', function () {
});

define('b', function () {
});

define('c', function () {
 // 这是最后的一次调用
});

我的做法是,假定每次的define调用都是最后的调用,在define里面设定一个timeout函数,这个timeout回调函数的工作就是检查pending变量。然后在define的开头检查这个timeout回调函数是否被设置了,如果被设置,那么说明前面的define不是最后一个,就通过clearTimeout来取消前面的timeout,然后再设置一个timeout,具体的实现看这里:实现。

要知道,通过timeout设置的回调函数,总是异步的。

EOF

Comments

comments powered by Disqus