前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nodejs(三)

nodejs(三)

作者头像
且陶陶
发布2023-04-12 15:42:22
4260
发布2023-04-12 15:42:22
举报
文章被收录于专栏:Triciaの小世界

规范

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

注意:要想使用ES6模块化规范

必须在 package.json 的根节点中添加 "type": "module" 节点

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

基本语法

默认导出 和 默认导入

语法:

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

默认导入的语法: import 接收名称 from '模块标识符'

默认导出

注意:默认导出只能导出一次

代码语言:javascript
复制
const money = 1000000

const userName = 'Tricia'
const age = 22
const sayHi = () => {
    console.log('hi')
}

// 注意:默认导出只能导出一次
export default {
    money,
    userName,
    age,
    sayHi
}

默认导入

代码语言:javascript
复制
// 导入核心模块
import fs from 'fs'

console.log(fs)

// 导入自定义模块
import a from './a.js'

console.log(a.userName)
a.sayHi()

按需导入导出

语法:

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

按需导入的语法: import { a } from '模块标识符'

按需导出

注意:

  1. 可以导出多次
  2. 导出的名字是什么,导入的名字必须也一样
代码语言:javascript
复制
// 按需导出
// 直接使用export 

// 注意:
// 1. 可以导出多次
// 2. 导出的名字是什么,导入的名字必须也一样

export const money = 100000
export const userName = 'Tricia'
export const sayHi = () => {
    console.log('hi~~~~~~~')
}

按需导入

导入的一定要加花括号

如果不想使用导出的名字 as表示重命名

代码语言:javascript
复制
import { money, userName, sayHi as say } from "./a.js"; // as表示重命名

console.log(userName)
say()
console.log(money)

直接导入

代码语言:javascript
复制
// 注意: 不需要加from
import './xxx.js'

同步异步

同步(synchronous)

sync 按顺序进行

异步(asynchronous)

async 同时进行

案例

代码语言:javascript
复制
console.log(1)

setTimeout(() => {
    console.log(2)
    setTimeout(() => {
        console.log(3)
    }, 0)
}, 0)

setTimeout(() => {
    setTimeout(() => {
        console.log(4)
    }, 0)
    console.log(5)
})

console.log(6)

// 结果:1 6 2 5 3 4

Event Loop 事件循环队列

JavaScript是单线程语言

单线程执行任务队列的问题:如果前一个任务非常耗时,则后续的任务就不得不一直等待。

为了防止某个耗时任务导致程序假死的问题,异步代码 由JavaScript 委托给宿主环境(node环境, 浏览器)进行等待执行

宿主环境 多线程的

代码语言:javascript
复制
setTimeout(() => {
    console.log(0)
}, 0)

console.log(1)
console.log(2)
console.log(3)
console.log(4)
console.log(5)

事件循环图解

异步函数 和 回调函数

异步函数:

  • setTimeout
  • setInterval
  • ajax
  • fs.readFile

回调函数:

  1. 把一个函数当成参数传递, 将来特定的时机调用, 这个函数就叫回调函数
  2. 一般什么时候会用到回调函数, 异步的时候 , 定时器, ajax (success, error)
代码语言:javascript
复制
console.log(1)

setTimeout(function() {
  console.log(2)
  
  setTimeout(function() {
    console.log(4)
  }, 1000)
  
  console.log(5)
}, 1000)

console.log(3)

回调函数缺点:

  1. 阅读性差,回调不会立马执行、
  2. 可维护性差,如果有大量嵌套,会有回调地狱!

promise

基本语法

  1. 创建
代码语言:javascript
复制
const p = new Promise((resolve, reject) => {
 	// promise内部一般可以封装一个异步操作
    // resolve, reject 是 promise 内部提供好给你的两个函数
	// 成功调用 resolve
	// 失败调用 reject
})
  1. 使用
代码语言:javascript
复制
p.then(res => { ... }) // 处理成功
 .catch(res => { ... }) // 处理失败

promise的三个状态

  • pending: 等待 (进行中)
  • fulfilled: 成功 (已完成), 调用了 resolve, promise的状态就会被标记成成功
  • rejected: 失败 (拒绝), 调用了 reject, promise的状态就会被标记成失败

💡 一旦promise的状态发生变化, 状态就会被凝固(即 不会再改变它的状态)

promise使用

代码语言:javascript
复制
// 模拟可以得到的薪资

// resolve函数: 调用resolve promise的状态会发生变化 pending -> fulfilled
// reject函数:调用reject promise的状态会发生变化 pending -> rejected

// 定义
const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        // 随机数   
        const money = Math.floor(Math.random() * (20000 - 10000)) + 10000
        console.log(money)
        if (money >= 14000) {
            resolve()
        } else {
            reject()
        }
    }, 3000)
})

// 调用
// 如果promise状态是pending 则都不执行
// 如果是fulfilled,.then()执行
// 如果是rejected,.catch()执行
p.then(() => {
    console.log('目标达成')
}).catch(() => {
    console.log('还要继续努力呀!!')
})

promise链式调用

如果有多个 promise 需要处理, 支持链式编程。

如果上一个 .then() 方法中返回了一个新的Promise 实例对象,则可以通过下一个 .then() 继续进行处理。

因此, .then() 方法是 Promise 支持链式调用的本质原因。

代码语言:javascript
复制
import fs from 'fs'
const read = (file) => {
    return new Promise((resolve, reject) => {
        fs.readFile(file, 'utf-8', (err, data) => {
            if (err) {
                reject(err)
            } else {
                resolve(data)
            }

        })
    })
}

// 按照顺序读取 a,b,c,d四个文件
// 不想读c文件,直接删掉就好,便于维护
read('a.txt')
    .then(data => {
        console.log(data)
        return read('b.txt')
    })
    .then(data => {
        console.log(data)
        return read('c.txt')
    })
    .then(data => {
        console.log(data)
        return read('d.txt')
    })
    .then(data => {
        console.log(data)
    })
    .catch(err => {
        console.log(err)
    })

promise 解决回调地狱

代码语言:javascript
复制
const p1 = new Promise(function (resolve, reject) {
  // promise 内部会封装一个异步的操作
  // resolve: 成功的时候, 需要调用
  // reject: 失败的时候, 需要调用
  fs.readFile('a.txt', 'utf8', (err, data) => {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})
const p2 = new Promise(function (resolve, reject) {
  fs.readFile('b.txt', 'utf8', (err, data) => {
    if (err) {
      reject(err)
    } else {
      resolve(data)
    }
  })
})
...
...
...

p1.then(res => {
  console.log(res)
  return p2
}).then(res => {
  console.log(res)
  return p3
}).then(res => {
  console.log(res)
  return p4
}).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

但是这个看起来也不简便,下面进行优化。

代码语言:javascript
复制
function read (filename) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filename, 'utf8', (err, data) => {
      if (err) {
        reject(err)
      } else {
        resolve(data)
      }
    })
  })
}

read('a.txt').then(res => {
  console.log(res)
  return read('b.txt')
}).then(res => {
  console.log(res)
  return read('c.txt')
}).then(res => {
  console.log(res)
  return read('d.txt')
}).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

💡 在 Promise 的链式操作中如果发生了错误,可以使用 .catch () 方法进行捕获和处理

Promise 的常用静态方法

Promise.all([ promise1, promise2, ... ]).then( ... )

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

Promise.race([ promise1, promise2, ... ]).then( .... )

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

async 和 await

async 和 await 是一对关键字.必须同时使用

async

async用于修饰一个函数, 表示一个函数是异步的.

如果async函数内没有await, 那么async没有意义的, 全是同步的内容

只有遇到了await开始往下, 才是异步的开始。

await

await 要用在 async 函数中。

await 后面一般会跟一个promise对象, await会阻塞async函数的执行,直到等到 promise成功的结果(resolve的结果)

await 只会等待 promise 成功的结果, 如果失败了会报错, 需要 try catch.

代码语言:javascript
复制
import fs from 'then-fs'

async function read() {
    const data1 = await fs.readFile('a.txt', 'utf-8')
    console.log(data1)
    const data2 = await fs.readFile('b.txt', 'utf-8')
    console.log(data2)
    const data3 = await fs.readFile('c.txt', 'utf-8')
    console.log(data3)
    const data4 = await fs.readFile('d.txt', 'utf-8')
    console.log(data4)

}
read()

// aaaa  bbbb  cccc   dddd

简单的测试一下~

代码语言:javascript
复制
// await之前的代码是同步的,await之后的代码是异步的
async function fn() {
    console.log('嘿嘿')
    const res = await fn2()
    console.log(res)
}
async function fn2() {
    await 1
    console.log('嘎嘎')
    return 100
}

fn()
console.log(222)

// 嘿嘿 222 嘎嘎 100

宏任务 微任务

宏任务:

主代码块, 定时器, 延时器的代码内容等都属于宏任务, 上一个宏任务执行完, 才会考虑执行下一个宏任务

微任务:

当前宏任务执行完,在下一个宏任务开始之前需要执行的任务, promise 的 .then .catch 中的代码都属于微任务

注意点:

  1. js 主线程遇到异步的内容, 交给浏览器去等待, 不会阻塞主线程
  2. 一定是满足条件后的任务, 才会被添加到任务队列

简单测试一下~

代码语言:javascript
复制
setTimeout(() => {
    console.log(1);
}, 0);
new Promise((resolve, reject) => {
    console.log(2);
    resolve('p1')
    new Promise((resolve, reject) => {
        console.log(3)
        setTimeout(() => {
            resolve('setTimeout2')
            console.log(4)
        }, 0)
        resolve('p2')
    }).then(data => {

        console.log(data)
    })
    setTimeout(() => {
        resolve('setTimeout1')
        console.log(5)
    }, 0);
}).then(data => {
    console.log(data)
})
console.log(6)

// 2 3 6 p2 p1 1  4 5
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 规范
  • 基本语法
    • 默认导出 和 默认导入
      • 语法:
      • 默认导出
      • 默认导入
    • 按需导入导出
      • 语法:
      • 按需导出
      • 按需导入
    • 直接导入
    • 同步异步
      • 同步(synchronous)
        • 异步(asynchronous)
          • 案例
          • Event Loop 事件循环队列
            • 事件循环图解
            • 异步函数 和 回调函数
              • 异步函数:
                • 回调函数:
                  • 回调函数缺点:
              • promise
                • 基本语法
                  • promise的三个状态
                    • promise使用
                      • promise链式调用
                        • promise 解决回调地狱
                          • Promise 的常用静态方法
                          • async 和 await
                            • async
                              • await
                                • 简单的测试一下~
                                • 宏任务 微任务
                                  • 宏任务:
                                    • 微任务:
                                      • 简单测试一下~
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档