Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一个复杂的包含resource场景的依赖,加载过程无法完成 #35

Closed
errorrik opened this issue Feb 5, 2015 · 1 comment
Closed

Comments

@errorrik
Copy link
Contributor

errorrik commented Feb 5, 2015

foo -> bar -> tpl!x
empty

如果tpl!x已经预先require并ready时

  • require(['foo'],callback) 时,callback被调用,但是未来foo模块将不存在
  • require(['foo', 'empty'],callback) 时,callback不被调用

原因是因为,modAutoDefine会对每个需要自动定义的模块进行modPrepare、modUpdatePreparedState、modTryInvoke调用。modUpdatePreparedState中,会尝试调用其依赖模块的modPrepare。如果模块包含resource依赖,modPrepare中会在尝试在resource加载完后重新调起modAutoDefine。当resource当前已经处于ready状态时,这个过程会马上发起。从而导致一个运行过程中,同一个模块的modUpdatePreparedState被重入。而modUpdatePreparedState中,对模块状态的写入没有做判断,从而导致模块状态可能从defined回退到prepared。

过程如下:

script onload -> modAutoDefine -> modPrepare(foo) -> modUpdatePreparedState(foo) -> modPrepare(bar) -> requireResource -> modAutoDefine -> modPrepare(foo)  -> modUpdatePreparedState(foo) -> modTryInvoke(foo) -> modTryInvoke(foo)

由于:

  1. resource加载完后重新调起modAutoDefine是合理的。因为resource加载可能是异步过程。所以这里不能干掉
  2. modUpdatePreparedState不可重入控制的话,增加代码量会多一些

所以,采用解决方案为:modUpdatePreparedState中,对模块状态的写入做判断

if (!modIs(id, MODULE_PREPARED) {
    mod.state = MODULE_PREPARED;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants