Java Script

循环加载指的是:在执行时依赖 b, b 的执行同时也依赖 a

一、Common Js 循环加载机制

    做法:一旦某个模块出现 “循环加载”,只输出执行部分未执行部分暂时不输出

a.js

exports.done = false;
var b = require('./b.js');

console.log(`Work in a.js, the value of b.done is ${b.done}`);

exports.done = true;
console.log(`a.js works finish`);

b.js

exports.done = false;
var a = require('./a.js');

console.log(`Work in b.js, the value of b.done is ${a.done}`);

exports.done = true;
console.log(`b.js works finish`);

    a 中 require('./b.js') 加载了 b ,  b 中也require('./a.js') 加载了a。两个模块形成了循环加载。

main.js

var a = require('./a.js');
var b = require('./b.js');
console.log('Work in main.js, a.done=%j, b.done=%j', a.done, b.done);

    main.js 运行步骤:

        (1) a 在运行到第二行时,开始加载 b, a 在第二行之后暂时不再执行,a中的done = false。

        (2) 带入到b中,b开始执行,b中的 a.done 就等于 false,b执行到最后,b中的done = true。

        (3) 再回到a,a继续执行,a中的b.done就是true。

执行结果

$ node main.js

Work in b.js, the value of b.done is false
b.js works finish

Work in a.js, the value of b.done is true
a.js works finish

Work in main.js, a.done=true, b.done=true

  

二、ES6 循环加载

    做法:ES6CommonJS 的做法不一样,ES6 在遇到加载命令 import 时,不会直接执行引用的模块,而是生成一个引用,等到应用到加载的模块时,再到加载模块中进行取值

    

    ES6的模块是动态引用,也就是说不会缓存对引用的数据,而是在使用的时候直接动态的获取。

    

// a.js

import { nodeB } from './b.js'
export function nodeA() {
	nodeB();
	console.log("Works finish")
}

nodeA();


// b.js

import { nodeA } from './a.js'

export function nodeB() {
	nodeA();
}

    

    如果是 CommonJs 上面的这组代码将会报错。因为 a 中第一行就加载了 b, 系统会先执行模块b,b又加载了a,但是模块a中第一行之后不会执行,所以模块b的加载a操作会报错。

    但是在 ES6 中,加载只是会生成一个引用,只有引用被使用时,才会需要在加载模块中获得时,模块b就可以正常运行了。

原文地址:https://www.cnblogs.com/Lyh1997/p/14330973.html