ES6模块化 Promise对象 async和await解决回调地狱问题

Node中的模块化

node.js 遵循了 CommonJS 的模块化规范。其中:

导入其它模块使用 require()方法

模块对外共享成员使用 module.exports 对象

ES6模块化规范 es6 模块化也是优先从缓存中加载

每个 js 文件都是一个独立的模块

导入其它模块成员使用 import 关键字

向外共享模块成员使用 export 关键字

ES6模块化语法 – 默认导入导出 package.json 文件中必须要有"type": "module",

默认导出的语法: export default 默认导出的成员

默认导入的语法: import 接收名称 from '模块路径'

 package.json 文件中必须要有"type": "module",

 ES6模块化语法 – 按需导入与按需导出

按需导出的语法: export const s1 = 10

按需导入的语法: import { 按需导入的名称 } from '模块路径'

 ES6模块化语法 –直接导入模块(无导出)

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

此时,可以直接导入并执行模块代码,语法:import '模块的路径'

 注意点:

导入JS文件,为了让JS代码执行一次

Vue 中,这种语法还可以导入 css、less等文件

promise

1promise 用于解决异步函数嵌套的问题 是一个构造函数 需要new进行创建实例

2promise 构造函数的形参接收的是一个函数 函数里面一定 要放入异步函数

3 promise  形参的函数 两个形参 一个是处理成功的结果 一个是处理失败的结果

4Promise then( )Cath( )可以处理成功和失败的结果 里面也是一个函数

例子:

// 导入fs 模块
import fs from 'fs' // 默认导入
// 1 promise 是一个构造函数 需要new进行创建实例
// 2 一般喜欢叫创建出的实例 为promise对象
// 3 promise 构造函数的形参接收的是一个函数 函数里面一定 要放入异步代码
let p1 =new Promise((resolve,reject)=>{  // 箭头函数里面的形参第一个是成功 第二个是失败
  fs.readFile('./tex/a.txt','utf-8',(err,data)=>{
    // 判断读取结果是否成功
    if(err){
    reject(err) //失败的
    }else{ 
    resolve(data) // 成功的
    }
  })
})
// 处理结果方法1
p1.then(
  result => console.log(result), //第一个函数处理成功
  error => console.log('读取文件失败:'+error.message) //第二函数处理失败
)
// 处理结果方法2 (重点掌握)
p1.then(result => console.log(result))
.catch(error=>console.log(error.message))

then方法的链式调用

如果前一个 then 返回一个普通值,则后一个 then 可以得到这个值
如果前一个then 返回一个 Promise 对象,则后一个 then 可以得到 Promise 对象成功状态的结果

new Promise((resolve, reject) => {
    resolve(1);
}).then(r1 => {
    console.log(r1); // 1
    return new Promise( /* resolve(2); 其他代码略 */ )
}).then(r2 => {
    console.log( r2 ); // 2
})

then-fs模块解决回调地狱

// 下载 then-fs:npm i then-fs
// 导入 模块
import thenFs from 'then-fs'
// 利用 then-fs 模块解决回调地狱
thenFs.readFile('./tex/a.txt','utf8').then(res=>{
  console.log(res)
  return thenFs.readFile('./tex/b.txt','utf8')
}).then(res=>{
  console.log(res)
  return thenFs.readFile('./tex/c.txt','utf8')
}).then(res=>{
  console.log(res)
})

Promise对象的同步异步

new Promise 的参数中的代码是同步执行
then 及 catch中的代码是异步执行

// 同步先执行 异步后执行
console.log(1)
new Promise((resolve,reject)=>{
  console.log(2)
  resolve()
  console.log(3)
}).then(res=>{
  console.log(4)
})
console.log(5)

// Promise 的构造函数中 和then catch 中的同步异步问题
// 12354
// new Promise 的参数中的代码是同步执行
// then 及 catch中的代码是异步执行

async await 修饰符

async  和  await  是  ES2017  中提出来的
async  和  await  两个关键字的出现, 简化的 Promise 的使用
async  用于修饰一个  function
async  修饰的函数,总是返回一个  Promise  对象
函数的返回值,将自动包装在  resolve  的  promise 
await  只能出现在  async  函数内
await  让  JS  引擎等待直到 promise 完成并返回结果
语法: let  value  = await  promise 对象 ;  //  等待 promise 对象的结果,然后将结果赋值给 value
由于 await 需要等待 promise 执行完毕,所以 await 会 暂停函数的执行 ,但不会影响其他同步任务
1.await只能出现在async修饰的函数中!
2.await后面跟随的是一个promise对象;
3.await能停止代码执行,让后面的同步代码,先执行;
4.await返回的是: Promise对象中的then()中的回调函数中的参数res

 async关键字

// 1.async 修饰的函数,总是返回一个 Promise 对象
async function fn(){
  console.log('我是fn函数')
 // 2.函数的返回值,将自动包装在 resolve 的 promise 中
  return 123
}
// 调用 注意 async 修饰符 不是异步函数
let result = fn()
// console.log(result)
// 证明async函数中return返回的数据 是被 promise 对象中resolve()抛出的数据
result.then(res=>console.log(res))

await关键字

// 定义一个async修饰的函数
async function getPromise(){
return '乖乖'
}

// 1.await只能出现在async修饰的函数中!
async function fn(){
  // 2.await后面跟随的是一个promise对象;
  // 4.await返回的是: Promise对象中的then()中的回调函数中的参数res;
  let str = await getPromise()
  console.log(str)
  console.log(123)
}

// 在这一句代码之前调用
fn()
// 3.await能停止代码执行,让后面的同步代码,先执行;
console.log('梦迪迪')

async和await解决回调地狱问题

// 导入then-fs模块
import thenFs from 'then-fs'
// 定义一个函数 用async修饰 将来方便使用 await 关键字
async function fn (){
  let str1 = await thenFs.readFile('./tex/a.txt','utf8')
  console.log(str1)
  let str2 = await thenFs.readFile('./tex/b.txt','utf8')
  console.log(str2)
  let str3 = await thenFs.readFile('./tex/c.txt','utf8')
  console.log(str3)
}
fn()

try和catch关键字

try catch 可以捕获错误 finally 一定执行

// 导入then-fs
import thenFs from "then-fs";
// 定义一个函数 用async 修饰 将来方便使用 await 关键字
async function fn(){ //try catch 可以捕获错误 finally 一定执行
 try{
  let str1= await thenFs.readFile('./tex/a.txt','utf8')
  console.log(str1)
  let str2= await thenFs.readFile('./tex/b.txt','utf8')
  console.log(str2)
  let str3= await thenFs.readFile('./tex/c.txt','utf8')
  console.log(str3)
 }catch(e){
 console.log(e.massage)
 }finally{
   console.log('执行完毕')
 }
}
fn()

案例:文件操作增删改查

// 利用async 和await 及 then-fs 封装增删改查
// 封装好的方法要返回数据
import thenFs from 'then-fs'
// es6模块化下 无法使用——dirname 所以使用相对路径
let url = './data.json'
// 按需导出
// 1 查询
export async function getData() {
  try {
    // 利用thenFs模块读取文件 转换为数组 返回
    let str = await thenFs.readFile(url, 'utf8')
    // 转换为数组 并返回
    let arr = JSON.parse(str)
    return arr
  } catch (e) {
    return ('获取失败')
  }
}
// 测试
/* getData().then(res=>{
  console.log(res)
}) */

// 2 添加
export async function addData(obj) {
  // 读取数据转换为数组
  let arr = await getData()
  // 向数组中添加元素 obj中添加id
  obj.id = arr[arr.length - 1].id * 1 + 1
  arr.push(obj)
  // 写入代码需要 try捕获错误
  try {
    await thenFs.writeFile(url, JSON.stringify(arr))
    return ('添加成功!')
  } catch (e) {
    return ('添加失败!')
  }
}
// 测试
/* addData({
  "bookname": "毛德洋",
  "author": "梦迪迪",
  "publisher": "深圳人民出版社"
}).then(res=>{
  console.log(res)
}) */

// 3删除
export async function delData(id) {
  // 读取数据转换为数组
  let arr = await getData()
  // 过滤
  let newArr = arr.filter(item => item.id != id)
  // 写入
  try {
    await thenFs.writeFile(url, JSON.stringify(newArr))
    return ('删除成功!')
  } catch (e) {
    return ('删除失败!')
  }
}
/* // 测试
delData(5).then(res => {
  console.log(res)
})
 */
// 4 修改
export async function putData(obj) {
  // 读取数据转换为数组
  let arr = await getData()
  // 修改删除在添加
  let index = arr.findIndex(item => item.id == obj.id)
  arr.splice(index, 1, obj)
  try {
    await thenFs.writeFile(url, JSON.stringify(arr))
    return ('修改成功!')
  } catch (e) {
    return ('修改失败!')
  }
}
// 测试
putData({
  "id": 4,
  "bookname": "毛德洋",
  "author": "梦迪迪",
  "publisher": "中国人民出版社"
}).then(res => {
  console.log(res)
})

// 默认导出
export default {
  getData,
  addData,
  delData,
  putData
}
[
  {
    "id": 1,
    "bookname": "三国演义",
    "author": "罗贯中",
    "publisher": "武汉人民出版社"
  },
  {
    "id": 2,
    "bookname": "水浒传",
    "author": "施耐庵",
    "publisher": "北京人民出版社"
  },
  {
    "id": 3,
    "bookname": "红楼梦",
    "author": "曹雪芹",
    "publisher": "铁岭人民出版社"
  },
  {
    "id": 4,
    "bookname": "毛德洋",
    "author": "梦迪迪",
    "publisher": "中国人民出版社"
  }
]

JS代码执行机制

js代码开始执行后,主线程执行栈中会把任务分为两类.

一类是同步任务, 一类是异步任务; 主线程执行栈优先执行同步任务,

异步任务会被放入特定的处理程序中,满足条件后,被放到消息(任务/事件)队列中,

主线程执行栈中所有的同步任务执行完毕之后,通过事件循环去消息(任务/事件)队列中,

挑选优先满足条件的程序,放入主线程执行栈中执行。事件循环,周而复始,一直执行。

 

宏任务和微任务

Tick会触发浏览器渲染,Promise不会触发,所以更加轻量级,多使用

 

宏任务

(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务

主线程上的执行栈中的代码

每次从事件队列中获取一个事件回调并放到执行栈中执行。

比如去银行排队办业务,每个人的业务就相当于是一个宏任务;

总结起来,宏任务有

setTimeout

setInterval

Ajax

事件

微任务

微任务(microtask)是宏任务中的一个部分,它的执行时机是在同步代码执行之后,下一个宏任务执行之前。

总结起来,微任务有:

Promise.then

process.nextTick(Node.js 环境)

Mac 查自己的ip的地址是 ifconfig

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值