1. ES6模块化
1.1 回顾node.js中如何实现模块化
node.js遵循了CommonJS
的模块化规范。其中:
- 导入其它模块使用
require()
方法 - 模块对外共享成员使用
module.exports
对象
1.2 前端模块化规范的分类
在ES6模块化规范诞生之前,JavaScript社区已经尝试并提出了AMD、CMD、Common]S等模块化规范。
但是,这些由社区提出的模块化标准,还是存在一定的差异性与局限性、并不是浏览器与服务器通用的模块化标准,例如:
- AMD和CMD适用于浏览器端的Javascript模块化
- CommonJS适用于服务器端的Javascript模块化
太多的模块化规范给开发者增加了学习的难度与开发的成本。因此,大一统的ES6模块化规范诞生了。
1.3 什么是ES6模块化规范
ES6模块化规范是浏览器端与服务器端通用的模块化开发规范。它的出现极大的降低了前端开发者的模块化学习成本,开发者不需再额外学习AMD、CMD或CommonJS等模块化规范。
ES6模块化规范中定义:
- 每个js文件都是一个独立的模块
- 导入其它模块成员使用import关键字
- 向外共享模块成员使用export关键字
1.4 在node.js中体验ES6模块化
node.js 中默认仅支持CommonJS
模块化规范,若想基于node.js体验与学习ES6的模块化语法,可以按照如下两个步骤进行配置:
① 确保安装了v14.15.1或更高版本的node.js
② 在package.json的根节点中添加"type": "module"
节点
1.5 ES6模块化的基本语法
ES6的模块化主要包含如下3种用法:
- 默认导出
export default{}
与默认导入import
- 按需导出
export
与按需导入import { s1 } from '模块标识符'
(可以使用as关键字重命名) - 直接导入并执行模块中的代码(如果只想单纯地执行某个模块中的代码,并不需要得到模块中向外共享的成员)
2. Promise
2.1 回调地狱
多层回调函数的相互嵌套,就形成了回调地狱。示例代码如下:
<script>
setTimeout(() => {
console.log('延时1秒后输出')
setTimeout(() => {
console.log('再延时2秒后输出')
setTimeout(() => {
console.log('再延时3秒后输出')
}, 3000)
}, 2000)
}, 1000)
</script>
回调地狱的缺点:
- 代码耦合性太强,牵一发而动全身,难以维护
- 大量冗余的代码相互嵌套,代码的可读性变差
为了解决回调地狱的问题,ES6(ECMAScript 2015)中新增了Promise 的概念。
2.2 Promise的基本概念
- Promise是一个构造函数
我们可以创建Promise的实例const p = new Promise()
,new出来的Promise实例对象,代表一个异步操作 - Promise.prototype上包含一个
.then()
方法
每一次new Promise()
构造函数得到的实例对象,都可以通过原型链的方式访问到.then()
方法,例如p.then()
.then()
方法用来预先指定成功和失败的回调函数
p.then(成功的回调函数,失败的回调函数)
p.then(result => { }, error => { })
调用.then()
方法时,成功的回调函数是必选的、失败的回调函数是可选的
2.3 基于回调函数按顺序读取文件内容
2.4 基于then-fs读取文件内容
由于node.js 官方提供的fs模块仅支持以回调函数的方式读取文件,不支持 Promise 的调用方式。因此,需要先运行如下的命令,安装then-fs
这个第三方包,从而支持我们基于Promise的方式读取文件的内容:npm install then-fs
2.4.1 then-fs的基本使用
调用then-fs提供的readFile()方法,可以异步地读取文件的内容,它的返回值是Promise的实例对象。因此可以调用.then()
方法为每个Promise异步操作指定成功和失败之后的回调函数。示例代码如下 :注意:上述的代码无法保证文件的读取顺序,需要做进一步的改进!
2.4.2 .then()方法的特性
如果上一个.then()
方法中返回了一个新的Promise实例对象,则可以通过下一个.then()
继续进行处理。通过.then()
方法的链式调用,就解决了回调地狱的问题。
2.4.3 基于Promise按顺序读取文件的内容
Promise支持链式调用,从而来解决回调地狱的问题。示例代码如下:
2.4.4 通过.catch捕获错误
在Promise的链式操作中如果发生了错误,可以使用Promise.prototy