ES6模块化的学习

一、ES6模块化

1. node.js中的模块化

node.js遵循CommonJS的模块化规范,其中

  • 导入其他模块使用require()方法
  • 模块对外共享使用module.exports对象

2. ES6模块化规范

2.1 ES6模块化规范中的定义

  • 每个js都是一个独立的模块
  • 导入其他模块使用 import 关键字
  • 向外共享模块使用 export 关键字

2.2 在node.js中使用ES6模块化

node.js仅支持CommonJS模块化规范,要使用ES6的规范需要进行如下配置:

  1. 确保安装了v14.15.1或更高版本的node.js
  2. 在package.json的根节点中添加 “type”:“module” 节点(cmd输入 npm init -y可以快速初始化package.json文件)

2.3 ES6模块化的基本语法

  • 默认导出与默认导入
  • 按需导出与按需导入
  • 直接导入并执行模块中的代码
2.3.1 默认导出与导入

默认导出: export default 要导出的内容
默认导入: import xxx from ‘xxxx’

每个模块中,export default仅允许使用一次

let name = "dudu"
let age = 23
function sayHello() {
    console.log("hello")
}
// 默认导出
export default {
    name,
    age,
    sayHello
}

//默认导入
import hello from './导出.js'
2.3.2 按需导出与按需导入

按需导出:export 按需导出的成员
按需导入:import { xxxx } from ‘xxxx’

// 按需导出
export function sayHello() {
    console.log("hello")
} 
export let name = "嘟嘟"

// 按需导入
import {name,sayHello} from './导出.js'
console.log(name)
sayHello()
  • 每个模块中可使用多次按需导出
  • 按需导入和按需导出时的名称要保持一致
  • 按需导入时,可以使用as关键字进行重命名
export let a = 23

import {a as age} from './导出.js'
console.log(age)
  • 按需导入可以和默认导入一起使用
import hello,{name,a as age,sayHello} from './导出.js'
2.3.3 直接导入并执行
import 'xxx/xxx'

二、 Promise

1. 回调地狱

回调地狱:多层回调函数的相互嵌套

setTimeout(() => {
    console.log("第一次回调")
    setTimeout(() => {
        console.log("第二次回调")
    }, 2000);
    setTimeout(() => {
        console.log("第三次回调")
    }, 3000);
}, 1000);

2. Promise

2.1 Promise的理解

  1. promise是一个构造函数
  • 可以通过new创建一个实例
  • new出来的Promise实例对象就代表一个异步操作
  1. promise的原型对象(prototype)上包含一个 .then() 方法
  2. .then()方法用来指定成功和失败的回调函数

fun.then(成功的回调,失败的回调)

  1. Promise用于避免回调地狱

2.2 then-fs异步读取文件

  • 安装 then-fs

cnpm install then-fs

  • 使用
    调用then-fs提供的 readFile() 方法,可异步读取文件内容,它的返回值是Promise实例对象
import thenFs from 'then-fs'
thenFs.readFile('./files/1.txt','utf-8')
    .then(resolve => {
        console.log(resolve)
    },err1 => {
        console.log(err1.message)
    })

thenFs.readFile('./files/2.txt','utf-8')
    .then(resolve => {
        console.log(resolve)
    },err2 => {
        console.log(err2.message)
    }) 

 thenFs.readFile('./files/3.txt','utf-8')
    .then(resolve => {
        console.log(resolve)
    },err3 => {
        console.log(err3.message)
    })
  • .then()的新特性
    上一个 .then() 方法若返回了一个新的Promise实例对象,则可以继续.then()调用
    此时可以通过 .catch 捕获错误,catch的位置可以提前(这样前面的错误不会导致后面的then无法执行)
import thenFs from 'then-fs'
thenFs
    .readFile('./files/1.txt','utf-8')
    .then(resolve => {
        console.log(resolve)
        return thenFs.readFile('./files/2.txt','utf-8')
    })
    .then(resolve => {
        console.log(resolve)
        return thenFs.readFile('./files/3.txt','utf8')
    })
    .then(resolve => {
        console.log(resolve)
    })
    .catch(err => {
        console.log(err.message)
    })

2.3 Promise.all()方法

Promise.all([Promise1,Promise2,…]) 方法可以把多个Promise实例包装为一个新的Promise实例

只有需要包装的多个Promise实例状态都为成功,新的Promise状态才为成功(等待机制)

const promiseArr = [
    thenFs.readFile('./files/1.txt','utf-8'),
    thenFs.readFile('./files/2.txt','utf-8'),
    thenFs.readFile('./files/3.txt','utf-8')
]

Promise.all(promiseArr)
        .then(result => {
            console.log(result) //[ '第一个文件', '第二个文件', '第三个文件' ]
        })

2.4 Promise.race()方法

Promise.race([promise1,promise2,…])用法和all()类似,
但是只要其中任何一个异步完成,就会立即执行下一步的.then()操作(赛跑机制)

Promise.race(promiseArr)
        .then(res => {
            console.log(res) //第一个文件
        })

三、 async/await

async/await是ES8引入的新语法,用于简化Promise异步操作
如果某个方法返回的是Promise实例,就可以使用await

async function getAllFile() {
   const res1 = await thenFs.readFile('./files/1.txt','utf8')
   console.log(res1)
   const res3 = await thenFs.readFile('./files/3.txt','utf8')
   console.log(res3)
   const res2 = await thenFs.readFile('./files/2.txt','utf8')
   console.log(res2)
}
getAllFile()
  • 如果方法内部使用了await则该方法必须被async修饰
  • 在async方法中,第一个await之前的方法会同步执行,await之后的方法会异步执行

四、 EventLoop

JavaScript是一门单线程语言,即同一时间只能做一件事

1. 同步任务和异步任务

  1. 同步任务
  • 非耗时任务,指主线程上排队执行的任务
  • 只有前一个同步任务执行完成,才能进行下一个同步任务
  1. 异步任务
  • 耗时任务,指由js委托给宿主环境(js的执行环境,如浏览器、node.js等)进行执行
  • 当异步任务执行完成后,会通知JavaScript主线程执行异步任务的回调函数

2. 同步任务和异步任务的执行过程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 面试题

// 同步任务
console.log('A') 

// 异步任务
thenFs.readFile('./files/1.txt','utf8')
    .then(res => {
        console.log('B')
    })

// 异步任务
setTimeout(() => {
    console.log('C')
}, 0);

// 同步任务
console.log('D') 

以上代码的输出顺序:A D C B

五、宏任务和微任务

异步任务分为宏任务和微任务

1. 宏任务

  • 异步Ajax请求
  • setTimeout、setInterval
  • 文件操作
  • 其他宏任务

2. 微任务

  • Promise.then、.catch、.finally
  • process.nextTick
  • 其它微任务

3. 执行顺序

宏任务和微任务是交替执行的
在这里插入图片描述
在这里插入图片描述

4. 例题

  1. 分析一下代码的输出顺序
setTimeout(() => {
    console.log('1')
});
new Promise( (resolve) => {
    console.log('2')
    resolve()
}).then(() => {
    console.log('3')
})
console.log('4')

在这里插入图片描述
在这里插入图片描述

6. 例题

// 同步任务
console.log('1')
// 宏任务
setTimeout(() => {
    // 同步任务
    console.log('2')
    // 同步任务
    new Promise((resolve) => {
        console.log('3')
        resolve()
    }).then(() => {
        // 异步任务
        console.log('4')
    })
});
// 同步任务
new Promise((resolve) => {
    console.log('5')
    resolve()
}).then(() => {
    // 微任务
    console.log('6')
})
// 宏任务
setTimeout(() => {
    // 同步任务
    console.log('7')
    // 同步任务
    new Promise((resolve) => {
        console.log('8')
        resolve()
    }).then(() => {
        // 微任务
        console.log('9')
    })
});

结果:1 5 6 2 3 4 7 8 9

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值