一.ES6 模块化 ??? 1.回顾node.js 中如何实现模块化 ??????? node.js遵循了CommonJS的模块化规范,其中: ??????? (1)导入其他模块使用require() 方法 ??????? (2)模块对外共享成员使用module.exports对象 ??? 2.? AMD和CMD 适用于浏览器端的Javascript 模块化 ??????? CommonJS 适用于服务器端的Javascript 模块化 ??????? ES6 模块化规范 浏览器端和服务器端通用的模块化规范 ??? 3.ES6 模块化规范中定义: ???????? 每个js文件都是一个独立的模块 ???????? 导入其它模块成员使用import 关键字 ???????? 向外共享模块成员使用export 关键字 ??????? ? ??????? 在node.js 中体验ES6 模块化 ??????????? 打开终端 -> npm init -y -> 在package.json 的根节点中加入 "type": "module" ??????????? type 的默认值是CommonJS ??????? node: CommonJS ??????? ES6: module ??? 4.ES6模块化的基本语法: ??????? 1.默认导出与默认导入?? ? ??????????? 1.默认导出的语法:export default 默认导出的成员 ??????????????? 如:export default{ ??????????????????????? n1, ??????????????????????? show ??????????????????? } ??????????? 2.默认导入的语法:import 接收名称 from '模块标识符' ??????????????? 如:import m1 from './1.默认导出.js'; ??????????? 3.默认导出的注意事项: ??????????????? 每个模块中,只允许使用唯一的一次export default,否则会报错 ?????????????? ? ??????? 2.按需导出和按需导入 ??????????? 1.按需导出的语法:export 按需导出的成员 ??????????????? 如:export let s1 = 'aaa'; ??????????????????? export function say(){}; ??????????? 2.按需导入的语法:import {s1 as str 2,say} from './3.按需导出.js' ??????????? 注意: ??????????????? (1)每个模块中可以使用多次按需导出 ??????????????? (2)按需导入的成员名称必须和按需导出的名称保持一致 ??????????????? (3)按需导入时,可以使用as 关键字进行重命名 ??????????????? (4)按需导入可以和默认导入一起使用 ??????????????????? 如: ??????????????????????? import info,{s1 as str 2,say} from './3.按需导出.js' ??????????????????????? 这里的info 就指向export default{} 导出的默认导出对象 ? ??????????????????????? info 是自己定义的变量名称??????? ? ??????? 3.直接导入并执行模块中的代码 ??????????? 如果只想单纯地执行某个模块中的代码,并不需要得到模块中向外共享的成员 ??????????? 如:import './5.直接运行模块中的代码.js'
二.Promise ??? 1.为了解决回调地狱的问题,ES6新增了Promise 的概念 ??? 2.Promise 的基本概念 ??????? 1.Promise 是一个构造函数 ??????????? 可以创建Promise 实例: const p = new Promise(); ??????????? new 出来的Promise 实例对象,代表一个异步操作 ??????? 2.Promise.prototype 上包含一个.then() 方法 ??????????? 每一次new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到.then() 方法 ??????????? 如:p.then() ??????????? 1.then() 方法用来预先指定成功和失败的回调函数 ??????????????? p.then(成功的回调函数,失败的回调函数) ??????????????? p.then(result => {},error => {}) ??????????????? 成功的回调函数是必选的,失败的回调函数是可选的 ??????????? 2.Promise 支持链式调用,从而解决回调地狱的问题 ??????????????? 基于Promise 异步按顺序读取文件内容 ??????????????? 如: ??????????????????? import thenFs from 'then-fs'; ??????????????????? thenFs.readFile('./files/1.txt','utf8') ??????????????????? .then((r1) => { ??????????????????????? console.log(r1); ??????????????????????? return thenFs.readFile('./files/2.txt','utf8'); ??????????????????? }).then((r2) => { ??????????????????????? console.log(r2); ??????????????????? }) ??????????????? readFile() 是一个Promise 实例对象 ??????????????? 如果上一个方法中返回的是一个新的Promise 实例对象,则可以链式使用.then() 方法 ??????? 3.通过.catch 捕获错误 ??????????? 在Promise 的链式操作中,如果发生了错误 ??????????? 可以使用Promise.prototype.catch 方法进行捕获和处理 ??????????? 如果不希望前面的错误导致后续的.then 无法正常执行,则可以将.catch 的调用提前 ??????????? 如: ??????????????? import thenFs from 'then-fs'; ??????????????? thenFs.readFile('./files/11.txt','utf8') ??????????????? .catch((err) => { ??????????????????? console.log(err.message); ??????????????? }) ??????????????? .then((r1) => { ??????????????????? console.log(r1); ??????????????????? return thenFs.readFile('./files/2.txt','utf8'); ??????????????? }).then((r2) => { ??????????????????? console.log(r2); ??????????????? }) ??????? 4.Promise.all() 方法 ??????????? Promise.all() 方法会发起并行的Promise 异步操作 ??????????? 等所有的异步操作全部结束后才会执行下一步的.then 操作(等待机制) ??????????? 如: ??????????????? import thenFs from 'then-fs'; ??????????????? const promiseArr = [ ??????????????????? thenFs.readFile('./files/1.txt', 'utf8'), ??????????????????? thenFs.readFile('./files/2.txt', 'utf8'), ??????????????????? thenFs.readFile('./files/3.txt', 'utf8'), ??????????????? ] ??????????????? Promise.all(promiseArr).then(result => { ??????????????????? console.log(result); ??????????????? }) ??????????? 执行顺序会按照数组中的顺序执行 ??????? 5.Promise.race() 方法 ??????????? Promise.race() 方法会发起并行的Promise 异步操作 ??????????? 只要任何一个异步操作完成,就立即执行下一步的.then 操作(赛跑机制) ??????? 6.基于Promise 封装读文件的方法 ??????????? 要求: ??????????????? 1.方法的名称要定义为getFile ??????????????? 2.方法接收一个形参fpath,表示要读取的文件的路径 ??????????????? 3.方法的返回值为Promise 实例对象
三.async/await ??? async/await 用来简化Promise 异步操作 ??? 1.async/await 的基本使用 ??????? 如果某个方法的返回值是一个Promise 实例对象,那么就可以在该方法前面用await 来修饰 ??????? 修饰完毕之后,该方法的返回值就不再是Promise 实例,而是变成了真正的值 ??????? 如果方法内部用到了await 那么该方法需要用async 来修饰 ??????? 如: ??????????? import thenFs from 'then-fs'; ??????????? async function getAllFile(){ ??????????????? const r1 = await thenFs.readFile('./files/1.txt','utf8'); ??????????????? console.log(r1);?? // 输出结果 111 ??????????? } ??????????? getAllFile(); ??????? 注意: ??????????? (1)如果在function 中使用了await,则function 必须被async 修饰 ??????????? (2)在async 方法中,第一个await 之前的代码会同步执行,第一个await 之后的代码会异步执行 ??????????????? 如: ??????????????????? import thenFs from 'then-fs'; ??????????????????? console.log('A'); ??????????????????? async function getAllFile(){ ??????????????????????? console.log('B'); ??????????????????????? const r1 = await thenFs.readFile('./files/1.txt', 'utf8'); ??????????????????????? const r2 = await thenFs.readFile('./files/2.txt', 'utf8'); ??????????????????????? const r3 = await thenFs.readFile('./files/3.txt', 'utf8'); ??????????????????????? console.log(r1,r2,r3); ??????????????????????? console.log('D'); ??????????????????? } ??????????????????? getAllFile(); ??????????????????? console.log('C'); ??????????????????? // 执行结果: ??????????????????? //???????? A ??????????????????? //???????? B ??????????????????? //???????? C ??????????????????? //???????? 111 222 333 ??????????????????? //???????? D
四.EventLoop ??? JS 是单线程执行的编程语言 ??? 如果前一个任务非常耗时,则后续的任务就不得不一直等待,导致程序假死的问题 ??? 1.同步任务 和 异步任务 ??????? 1.同步任务 和 异步任务的概念 ??????????? (1)同步任务:sync ??????????????? 又叫做非耗时任务,指主线程上排队执行的那些任务 ??????????????? 只有前一个任务执行完毕,才能执行后一个任务 ??????????? (2)异步任务:async ??????????????? 又叫做耗时任务,异步任务由JS委托给宿主环境进行执行(宿主环境:浏览器 or Node.js) ??????????????? 当异步任务执行完成后,会通知JS主线程执行异步任务的回调函数 ??????? 2.同步任务和异步任务的执行过程 ??????????? (1)同步任务由JS主线程按次序执行 ??????????? (2)异步任务委托给宿主环境执行(浏览器 or Node.js) ??????????? (3)已完成的异步任务对应的回调函数,会被加入到任务队列中等待执行 ??????????? (4)JS 主线程的执行栈被清空后,会读取任务队列中的回调函数,按次序执行 ??????????? (5)JS主线程会不断重复第4步 ??? 2.EventLoop 的基本概念 ??????? 事件循环: ??????????? JS主线程从“任务队列”中读取异步任务的回调函数,放到执行栈中依次执行,这个过程是循环不断的 ??????? 面试题: ??????????? import thenFs from 'then-fs'; ??????????? console.log('A'); ??????????? thenFs.readFile('./files/1.txt','utf8').then(dataStr => { ??????????????? console.log('B'); ??????????? }) ??????????? setTimeout(() => { ??????????????? console.log('C'); ??????????? },0) ??????????? console.log('D'); ??????????? // 输出结果: ADCB ??????????? 解释: ??????????????? A 和D 属于同步任务,会根据代码的先后顺序一次被执行 ??????????????? C 和B 属于异步任务,他们的回调函数会被加入到任务队列中,等待主线程空闲时再执行
五.宏任务和微任务 ??? 1.概念 ??????? 异步任务(耗时任务)又分为宏任务和微任务 ??????? 宏任务:异步Ajax、setTimeout、setInterval、文件操作等 ??????? 微任务:Promise.then、Promise.catch、Promise.finally等 ??? 2.宏任务和微任务的执行顺序 ??????? 每一个宏任务执行完之后,都会检查是否存在待执行的微任务 ??????? 如果有,则执行完所有微任务之后,再继续执行下一个宏任务 ??? 3.面试题: ??????? setTimeout(function(){ ??????????? console.log('1'); ??????? }) ??????? new Promise(function(resolve){ ??????????? console.log('2'); ??????????? resolve(); ??????? }).then(function(){ ??????????? console.log('3'); ??????? }) ??????? console.log('4'); ??????? // 输出结果:2431 ??????? 解释: ??????????? new Promise 是一个同步任务,先执行 ??????????? Promise.then() 是微任务 ??????????? setTimeout() 是宏任务 ??? 4.面试题: ??????? console.log('1'); ??????? setTimeout(function(){ ??????????? console.log('2'); ??????????? new Promise(function(resolve){ ??????????????? console.log('3'); ??????????????? resolve(); ??????????? }).then(function(){ ??????????????? console.log('4'); ??????????? }) ??????? })
??????? new Promise(function(resolve){ ??????????? console.log('5'); ??????????? resolve(); ??????? }).then(function(){ ??????????? console.log('6'); ??????? })
??????? setTimeout(function(){ ??????????? console.log('7'); ??????????? new Promise(function(resolve){ ??????????????? console.log('8'); ??????????????? resolve(); ??????????? }).then(function(){ ??????????????? console.log('9'); ??????????? }) ??????? }) ??????? // 输出结果:156234789
六.API接口案例 ?? ?
|