es6模块+异步promise+async/await

ES6模块化

前端模块化分类

es6模块化诞生之前,js社区尝试提出了AMD,CMD,Commjs模块化规范

AMD,CMD适用于浏览器端的JavaScript模块化

CommonJs适用于服务器端的JavaScript模块化

Es6即适用于浏览器端也适用于服务器端

ES6模块化规范中定义

  • 每个js文件都是一个独立的模块
  • 导入其它模块成员使用import
  • 向外共享模块成员使用export
nodejs默认仅支持CommonJs模块化规范,想基于node.js体验es6的模块化,需要配置
1:安装了v14.15.1或更高版本的node
2:在package.json的根节点中添加   "type":"module"  节点
默认导出

export default 默认导出的成员

var a = 10;
function show () {

}
const arr =[11,22,333]
export default {
  a,
  show
}

注意:每个模块中,只允许使用唯一的一次export default ,否则会报错!

默认导入

注意: 默认导入时接收名称可以任意名称,只要是合法的成员名称就可以

// 导入export default 向外共享的成员
import aa from './module/index.js';
console.log(aa);  //{ a: 10, show: [Function: show] }
按需导入
import aa,{s1} from './module/index.js'

console.log(s1)
// 导入export default 向外共享的成员
// 默认导入时接收名称可以任意名称,只要是合法的成员名称就可以
// import aa from './module/index.js';
console.log(aa);  //{ a: 10, show: [Function: show] }
按需导出
var a = 10;
function show () {
  
}
const arr = [11, 22, 333]

// 按需导出
export let s1 = "aaa";
export function say () { }
export let s2 = true;

export default {
  a,
  show
}
按需导入和按需导出注意事项
  • 每个模块中可以使用多次按需导出
  • 按需导入的成员名称必须和按需导出的名称保持一致
  • 按需导入时,可以使用as进行重命名
  • 按需导入可以和默认导入一起使用
import aa,{s1 as a} from './module/index.js'

console.log(a)
// 导入export default 向外共享的成员
// 默认导入时接收名称可以任意名称,只要是合法的成员名称就可以
// import aa from './module/index.js';
console.log(aa);  //{ a: 10, show: [Function: show] }
直接导入并执行模块中的代码

如果只想单纯的执行某个模块中的代码,并不需要得到模块中向外共享的成员

for (let i = 0; i < 3; i++){
  console.log(i)
}
import './module/m1.js'

promise

回调地狱

多层回调函数的相互嵌套,就形成了回调函数

缺点:

  • 代码难以维护
  • 大量冗余的代码相互嵌套,可读性差
setTimeout(()=>{
  setTimeout(()=>{
     setTimeout(()=>{
     },1000)
  },2000)
},1000)
如何解决回调地狱

ES6中新增了Promise的概念

  • Promise是一个构造函数
    • 创建一个promise实例 const p =new Promise()
    • new出来的promise实例对象,代表一个异步操作
  • Promise.prototype上包含一个.then方法
    • 每一次new Promise()构造函数得到的实例对象
    • 都可以通过原型链的方式访问到.then方法
  • .then()方法用来预先指定成功和失败的回调函数
p.then(成功的回调函数,失败的回调函数)
p.then(()=>{},()=>{})

调用.then方法时,成功的回调函数是必选的,失败的回调函数是可选的

  • catch方法 对错误的捕获和处理
基于then-fs读取文件内容

由于nodejs官方提供的fs模块仅支持以回调函数的方式读取文件,不支持promise的调用方式

所以安装then-fs 第三方包,支持基于promise的方式读取文件

  • 下载
  npm install then-fs
  • 使用

then-fs提供的readFile方法,可以异步的读取文件内容,它的返回值是Promise的实例对象

因此可以调用.then()方法为每个promise异步操作指定成功和失败之后的回调函数

import thenFs from "then-fs";
// thenFs.readFile('./files/1.txt', 'utf8') 返回promise实例对象
thenFs.readFile('./files/1.txt', 'utf8')//objf1
  
  .then(d1 => { //成功执行
    console.log(d1,"d1")   //窗前明月光 d1
    return thenFs.readFile('./files/2.txt','utf8')
  })
  //objf1.then(objf2) === objf2
  
  .then(d2 => {
    console.log(d2, "d2");  //hello d2
    return thenFs.readFile('./files/3.txt','utf8')
  })
  //objf2.then(objf3) === objf3
  
  .then(d3 => {
    console.log(d3, "d3");  //13333 d3
    return 8;
  })
  //objf3.then(8) === objf3.then(value = 8)

  .then(d4 => {
    console.log(d4, "d4");//8 d4
  })
  .catch(err1 => {  //失败执行
    console.log(err1,0)
  })

前一个回调函数的返回值是后一个回调函数的参数

all()方法

Promise.all()方法会发起并行的Promise异步操作,等所有的异步操作全部结束后才会执行下一步的.then操作

import thenFs from "then-fs"
// 1定义一个数组  存放3个文件的异步操作
const promiseArr = [
  thenFs.readFile('./files/1.txt', 'utf8'),
  thenFs.readFile('./files/2.txt', 'utf8'),
  thenFs.readFile('./files/3.txt','utf8')
]
// 并行  只要有一个报错就都报错
// 2将promise的数组,作为Promise.all()的参数
Promise.all(promiseArr)
  .then(([d1, d2, d3]) => {
      console.log(d1,d2,d3)
  })
  .catch(err => {
    console.log(err)
  })
race

不常用
Promise.race()方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的.then操作

import thenFs from "then-fs"
// 1定义一个数组  存放3个文件的异步操作
const promiseArr = [
  thenFs.readFile('./files/1.txt', 'utf8'),
  thenFs.readFile('./files/2.txt', 'utf8'),
  thenFs.readFile('./files/3.txt','utf8')
]
// 并行  只要有一个报错就都报错
// 2将promise的数组,作为Promise.race()的参数
Promise.race(promiseArr)
  .then((result) => {
    // 只要任何一个异步操作完成,就立即执行成功的回调函数
     console.log(result)
  })
  .catch(err => {//捕获promise异步操作的错误
    console.log(err)
  })
基于promise封装读文件的方法
要求:
1:方法的名称getFile
2:方法接收一个参数 fpath ,表示要读取文件的路径
3:方法的返回值为promise实例对象
getFile方法的基本定义

只是创建了一个形式上的异步操作

// 1:名称为getFile
// 2:接收参数,要读取文件的路径

function getFile (fpath) {
  // 3方法的返回值为Promise的实例对象
  return  new Promise()
}
创建具体的异步操作

需要在new Promise()构造函数中传递一个function函数,将具体的异步操作定义到function函数内部

function getFile (fpath) {
  // 3方法的返回值为Promise的实例对象
  return new Promise(function () {
    // 4这是一个具体的读文件的异步操作
     fs.readFile(fpath,'utf8',(err,data)=>{})
  })
}
获取.then的两个实参

通过.then()指定的成功和失败的回调函数,可以在function的形参中进行接收

function getFile (fpath) {
  // 3方法的返回值为Promise的实例对象

  // 5形参 resolve  调用getFile()方法时  通过.then指定的成功的回调函数
  // 5形参 reject   调用getFile()方法时  通过.then指定的失败的回调函数
  return new Promise(function (resolve,reject) {
    // 4这是一个具体的读文件的异步操作
     fs.readFile(fpath,'utf8',(err,data)=>{})
  })
}

// 调用getFile()
// getFile('./files/1.txt').then(成功的回调函数,失败的回调函数)
调用resolve和reject回调函数

Promise异步操作的结果,可以调用resolve或reject回调函数进行处理

// 1:名称为getFile
// 2:接收参数,要读取文件的路径

function getFile (fpath) {
  // 3方法的返回值为Promise的实例对象

  // 5形参 resolve  调用getFile()方法时  通过.then指定的成功的回调函数
  // 5形参 reject   调用getFile()方法时  通过.then指定的失败的回调函数
  return new Promise(function (resolve,reject) {
    // 4这是一个具体的读文件的异步操作
    fs.readFile(fpath, 'utf8', (err, data) => {
      // 只能有一个状态  要么成功 要么失败
      if (err) return reject(err)  //如果读取失败  调用失败的回调函数
      // 读取成功的数据会随着resolve返回  返回给.then的成功的回调函数的形参
      resolve(data)
     })
  })
}

// 调用getFile()
// getFile('./files/1.txt').then(成功的回调函数,失败的回调函数)

getFile('./files/1.txt').then((res) =>{
  console.log(res, "res");
}, (err) => {
  console.log(err, "err");
})

关于异步的理解:
群友:加载页面的时候还能执行其他功能就是异步
老师:异步都有回调函数,但回调函数不一定是异步

async/await

async/await 是ES8引入的新语法,用来简化Promise异步操作,在async/await出现之前,我们只能通过.then的方式处理promise异步操作

使用
import thenFs from "then-fs";
// 按照顺序读取文件
async function getAllFile () {
  const d1 = await thenFs.readFile('./files/1.txt', 'utf8')
  console.log(d1)
  const d2 = await thenFs.readFile('./files/2.txt', 'utf8')
  console.log(d2)
  const d3 = await thenFs.readFile('./files/3.txt', 'utf8')
  console.log(d3)
}
getAllFile ()

如果在function中使用了await ,那么function 必须被async修饰

在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行

用同步的方式写代码,执行的是异步
thenFs.readFile()是异步

import thenFs from "then-fs";
// 按照顺序读取文件
async function getAllFile () {
  console.log(123);
  // await  等待后面的异步执行完  再执行下面的代码
  const d1 = await thenFs.readFile('./files/1.txt', 'utf8')
  const d2 = await thenFs.readFile('./files/2.txt', 'utf8')
  const d3 = await thenFs.readFile('./files/3.txt', 'utf8')
  console.log(d1, d2, d3);
  console.log("D");
}

getAllFile()
// 123
// 窗前明月光 hello 13333
// D

比如:
先请求完接口1,拿接口1返回的数据,去当作接口2的请求参数

用同步的方式,执行异步操作

async/await是一种语法糖,和promise一样都是为了解决回调地狱

async意思是将函数变为异步函数,函数内部必有异步操作
await的意思是等待,等待后面的异步执行完 再执行下面的代码

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值