ES6的模块化规定统一了浏览器端和服务器端的模块开发规范,让开发更有效率
ES6的模块化用法
1. 默认导入导出
//默认导入
import fs from 'fs'
//默认导出 仅能使用一次导出!!
export default{
n1,
m1,
}
2.按需导入导出
//按需导入 可在导入时重命名
import {s1,b2} from './some.js'
import {s1,b2 as b1} from './some.js' //将b2改为b1
//按需导出 也可以多次导出
export let s1 ='one'
export function b2(){...}
直接导入
//直接导入不需要得到模块成员 ,只是需要该模块运行起来
import './some.js'
解决回调地狱
通过新添加的promise构造函数的
.then
方法来解决多个回调函数连续调用的问题 promise一旦出现结果就不能更改(resolve reject) 不管有多少个只会第一个生效 Promise的 .then() 回调函数是微任务
.then()
方法里包含两个回调函数:
- 成功的回调(必须有)
- 失败的回填 (可以没有) ```javascript import thenFs from ‘then-fs’
thenFs.readFile(‘./files/1.txt’, ‘utf-8’) // 得到的结果就是一个 promise 对象 .then(result => { console.log(result) return thenFs.readFile(‘./files/2.txt’, ‘utf-8’) // 如果在成功的回调中继续返回一个 promise 对象,则可继续在后面 .then() 指定回调函数 }) .then(result => { // 这里的结果 就是上一个回调函数中 返回的 promise 异步任务的结果 console.log(result) return thenFs.readFile(‘./files/3.txt’, ‘utf-8’) }) .then(result => { console.log(result) })
<a name="hQKj2"></a>
## .catch()方法来捕获错误
> `.catch()`错误捕获将会在出现错误时执行捕获错误,并执行`.catch()`后面的代码(如果有的话)
- 当`.catch()`放在代码的最后面时,中间代码只要出错就不会执行
- 当`.catch()`放在出错代码的下面,出错部分不执行,而catch执行,后面的代码依旧会执行
```javascript
import thenFs from 'then-fs'
thenFs.readFile('./files/11.txt', 'utf8')
//在这里的.catch()函数会执行出错代码
.then((r1) => {
console.log(r1)
return thenFs.readFile('./files/2.txt', 'utf8')
})
.then((r2) => {
console.log(r2)
return thenFs.readFile('./files/3.txt', 'utf8')
})
.then((r3) => {
console.log(r3)
})
.catch((err) => { //如果前面出错将只执行此处及下方代码
console.log(err.message)
})
Promise.all
立即执行所有的Promise异步操作,等所有的异步操作的执行完毕后再执行下一步的.then()
import thenFs from 'then-fs'
const promiseArr = [
thenFs.readFile('./files/3.txt', 'utf8'),
thenFs.readFile('./files/2.txt', 'utf8'),
thenFs.readFile('./files/1.txt', 'utf8'),
]
Promise.all(promiseArr).then(result => {
console.log(result)
})
async和await使用
- await将promise实例内的值解析出来传给变量
- 因为await只能在异步函数内执行,需要async将函数转为异步函数 ```javascript import thenFs from ‘then-fs’
console.log(‘A’) async function getAllFile() { console.log(‘B’) const r1 = await thenFs.readFile(‘./files/1.txt’, ‘utf8’) console.log(r1) const r2 = await thenFs.readFile(‘./files/2.txt’, ‘utf8’) console.log(r2) const r3 = await thenFs.readFile(‘./files/3.txt’, ‘utf8’) console.log(r3) console.log(‘D’) }
getAllFile() console.log(‘C’)
``` 在 async 方法中,第一个 await 之前的代码会同步执行,await 之后的代码会异步执行;
同步任务与异步任务
js属于单线程语言,所有就需要通过异步函数来解决那些费时的函数
- 同步任务(synchronous):又叫做非耗时任务,指的是在主线程上排队执行的那些任务,只有前一个任务执行完毕,才能执行后一个任务
- 异步任务(asynchronous) :又叫做耗时任务,异步任务由 JavaScript 委托给宿主环境进行执行,当异步任务执行完成后,会通知 JavaScript 主线程执行异步任务的回调函数
- JS主线程会依次执行同步任务
- 发现有异步任务会委托给宿主环境执行异步任务
- 主线程的执行栈被清空后,会读取任务队列中的回调函数,次序执行
Event Loop 事件循环
JS引擎常驻于内存中,等待宿主将JS代码或函数传递给它。
也就是等待宿主环境分配宏观任务,反复等待 - 执行即为事件循环。
Event Loop中,每一次循环称为tick,每一次tick的任务如下:
- 执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
- 检查是否存在微任务,有则会执行至微任务队列为空;
- 如果宿主为浏览器,可能会渲染页面;
- 开始下一轮tick,执行宏任务中的异步代码(setTimeout等回调)。
宏任务和微任务
目前所知的宏任务为:
- setTimeout/setInterval(定时器)
- 最外层执行的代码 即刚运行时所执行的最外层代码也是宏任务
微任务为:
- 一切和promise相关的函数,包括受到async和await影响的函数
在代码刚执行时,为宏任务,此时如果最外层代码执行完毕后,会检查微任务队列里是否有待执行的微任务,如果有就全部执行,再执行下一个宏任务,也就是说 在宏任务执行完毕后再执行下一个宏任务时会检查是否有等待执行的微任务,并将其执行