docs(module): edit import()

This commit is contained in:
ruanyf
2017-02-14 07:32:28 +08:00
parent e5c9ccadca
commit 2da8eac664
4 changed files with 137 additions and 23 deletions
+113 -4
View File
@@ -622,7 +622,9 @@ import {db, users} from './constants';
## import()
上面说过了,`import`语句会被JavaScript引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。所以,下面的代码会报错。
### 简介
前面介绍过,`import`命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适)。所以,下面的代码会报错。
```javascript
// 报错
@@ -631,9 +633,9 @@ if (x === 2) {
}
```
上面代码中,引擎处理`import`语句是在执行之前,所以`import`语句放在`if`代码块之中毫无意义,因此会报句法错误,而不是执行时错误。
上面代码中,引擎处理`import`语句是在编译时,这时不会去分析或执行`if`语句,所以`import`语句放在`if`代码块之中毫无意义,因此会报句法错误,而不是执行时错误。也就是说,`import``export`命令只能在模块的顶层,不能在代码块之中(比如,在`if`代码块之中,或在函数之中)。
这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块。从长远来看,`import`语句会取代 Node 的`require`方法,但是`require`是运行时加载模块,`import`语句显然无法取代这种动态加载功能。
这样的设计,固然有利于编译器提高效率,但也导致无法在运行时加载模块。从语法上,条件加载就不可能实现。如果`import`命令要取代 Node 的`require`方法,这就形成了一个障碍。因为`require`是运行时加载模块,`import`命令无法取代`require`动态加载功能。
```javascript
const path = './' + fileName;
@@ -648,7 +650,7 @@ const myModual = require(path);
import(specifier)
```
上面代码中,`import`函数的参数`specifier`,指定所要加载的模块的位置。`import`语句能够接受什么参数,`import()`函数就能接受什么参数,两者区别主要是后者为动态加载。
上面代码中,`import`函数的参数`specifier`,指定所要加载的模块的位置。`import`命令能够接受什么参数,`import()`函数就能接受什么参数,两者区别主要是后者为动态加载。
`import()`返回一个 Promise 对象。下面是一个例子。
@@ -668,3 +670,110 @@ import(`./section-modules/${someVariable}.js`)
`import()`类似于 Node 的`require`方法,区别主要是前者是异步加载,后者是同步加载。
### 适用场合
下面是`import()`的一些适用场合。
1)按需加载。
`import()`可以在需要的时候,再加载某个模块。
```javascript
button.addEventListener('click', event => {
import('./dialogBox.js')
.then(dialogBox => {
dialogBox.open();
})
.catch(error => {
/* Error handling */
})
});
```
上面代码中,`import()`方法放在`click`事件的监听函数之中,只有用户点击了按钮,才会加载这个模块。
2)条件加载
`import()`可以放在`if`代码块,根据不同的情况,加载不同的模块。
```javascript
if (condition) {
import('moduleA').then(...);
} else {
import('moduleB').then(...);
}
```
上面代码中,如果满足条件,就加载模块 A,否则加载模块 B。
3)动态的模块路径
`import()`允许模块路径动态生成。
```javascript
import(f())
.then(...);
```
上面代码中,根据函数`f`的返回结果,加载不同的模块。
### 注意点
`import()`加载模块成功以后,这个模块会作为一个对象,当作`then`方法的参数。因此,可以使用对象解构赋值的语法,获取输出接口。
```javascript
import('./myModule.js')
.then(({export1, export2}) => {
// ...·
});
```
上面代码中,`export1``export2`都是`myModule.js`的输出接口,可以解构获得。
如果模块有`default`输出接口,可以用参数直接获得。
```javascript
import('./myModule.js')
.then(myModule => {
console.log(myModule.default);
});
```
上面的代码也可以使用具名输入的形式。
```javascript
import('./myModule.js')
.then(({default: theDefault}) => {
console.log(theDefault);
});
```
如果想同时加载多个模块,可以采用下面的写法。
```javascript
Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
])
.then(([module1, module2, module3]) => {
···
});
```
`import()`也可以用在 async 函数之中。
```javascript
async function main() {
const myModule = await import('./myModule.js');
const {export1, export2} = await import('./myModule.js');
const [module1, module2, module3] =
await Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
]);
}
main();
```