关于ES6的module的循环加载
今天写js时,碰到了一个模块循环加载的错误,下面时例子:
// testa.mjs import testb from './testb.mjs'; const {b} = testb; const a = { ccc: 'ccc', }; console.log(`aa:${a}`); console.log(`ab:${b}`); export default { a, }; // testb.mjs import testa from './testa.mjs'; const {a} = testa; const b = { ddd: 'ddd', }; console.log(`ba:${a}`); console.log(`bb:${b}`); export default { a, };
运行testa.mjs后结果为:
testa is not defined
at .../testb.mjs:3:13
翻了翻ES6入门中关于循环加载的部分,猜测JavaScript运行时,碰到import是直接进入引入的模块,运行一遍后再返回原模块运行接下来的代码
翻了翻谷歌的结果,看见有人说“一个避免出问题的方法就是少写立即执行的代码,尽量使用函数封装起来,需要的时候调用函数,就不会出错了。”
故把代码修改成如下:
// testa.mjs import testb from './testb.mjs'; const {b} = testb; const a = { ccc: 'ccc', }; console.log(`aa:${a.ccc}`); console.log(`ab:${b.ddd}`); b.ba(); export default { a, }; // testb.mjs import testa from './testa.mjs'; const b = { ddd: 'ddd', ba() { const { a } = testa; console.log(`ba:${a.ccc}`); console.log(`bb:${b.ddd}`); }, };
console.log(`bb:${b.ddd}`); export default { a, };
运行后发现还是报错,但是已经输出bb,aa,ab了,与猜想相同。
看了看错误代码:
testa is not defined
at Object.ba (.../testb.mjs:6:19)
at .../testa.mjs:11:3
猜测是在改行调用b.ba()时,testa并未进行模块的输出(指未执行到export default...),故在其外包裹一个0s延迟的setTimeout,代码就如所想的一样执行了。
注:此处0s延时的setTimeout用处是使内部的代码变为异步,其会在其他同步的JavaScript代码运行完毕后再运行,故此时testa已执行了模块的输出,所以并不会报错了。