关于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已执行了模块的输出,所以并不会报错了。

posted @ 2019-04-19 13:13  FreezeNow  阅读(368)  评论(0编辑  收藏  举报