Node.js 中阻塞、非阻塞及异步特性

Node.js 中阻塞、非阻塞及异步特性

前言

  • 看一下我们之前写的代码
vue 复制代码
const fs = require('fs')
const textIn = fs.readFileSync('./txt/input.txt','utf-8')
console.log(textIn)

这个有什么问题呢?这串代码是同步的,同步的意思就是你必须等待上一行代码完全运行完毕之后你才可以运行下一行代码;这就是意味着如果你这行代码发生问题,这行代码就会阻塞下一行代码的运行,这样并不是好的办法。

  • 所以我们可以采用异步的方式,如下
vue 复制代码
const fs = require('fs');
fs.readFile('./txt/input.txt','utf-8',(err,data)=>{
    console.log(data)
});
console.log('文件正在读取中......');

我们发现这样就不会导致代码异常来导致阻塞了;

Node.js的异步特性

  1. 非阻塞I/O

例如发起文件读取、网络请求等耗时操作的操作的时候,不会等待结果返回,而且立刻执行后续代码;当耗时任务完成后,通过回调函数、Promise或者async/await处理结果(学习JavaScript的时候,你一定学习过回调地狱的问题,想要避免它,目前就可以Promise或async/await的方式来解决);

  1. 事件循环

node.js单线程可以并发处理大量请求的原因就是使用事件循环不断检查任务队列,例如一些定时器、I/O请求、微任务等,按照阶段依次运行;

回调并不能代表异步,这些我们要自己去实现,而node.js中的像readfile这样的是Node实现的,我们需要使用它就自带这个特性

实际演示

javascript 复制代码
fs.readFile('./txt/start1.txt','utf-8',(err,data) => {
    if(err) return console.log('发生了错误');
    console.log(data);
})
  • 这个文本只有一个内容,read-this,而有一个read-this.txt里面有实际内容
vue 复制代码
fs.readFile('./txt/start.txt','utf-8',(err,data) => {
    if(err) return console.log('发生了错误');
    console.log(data);
    fs.readFile(`./txt/${data}.txt`,'utf-8',(err,data1) => {
        console.log(data1)
        })
})
  • 紧接着,我们在读取一个文档
vue 复制代码
fs.readFile('./txt/start.txt','utf-8',(err,data) => {
    if(err) return console.log('发生了错误');
    console.log(data);
    fs.readFile(`./txt/${data}.txt`,'utf-8',(err,data1) => {
        console.log(data1)
    fs.readFile('./txt/append.txt','utf-8',(err,data2)=>{
        console.log(data2)
    })
        })
})
  • 继续折腾,创建一个文档,合并一下上面两个文档
vue 复制代码
fs.readFile('./txt/start.txt','utf-8',(err,data) => {
    if(err) return console.log('发生了错误');
    console.log(data);
    fs.readFile(`./txt/${data}.txt`,'utf-8',(err,data1) => {
        console.log(data1)
    fs.readFile('./txt/append.txt','utf-8',(err,data2)=>{
        console.log(data2)
    fs.writeFile('./txt/final.txt',`${data1}\n${data2}`,'utf-8',err => {
        console.log('文件成功写入!');
        })
     })
 })
})
  • 上面就是node.js使用回调函数来完成异步特性的,但是是不是看上去非常难以理解,现代我们会使用Promise或者async/await来解决这个问题,让其看起来更加明朗;
javascript 复制代码
const fs = require('fs').promises;
async function  processFiles() {
    try{
        //1.读取start.txt,获取文件名
        const fileName = await fs.readFile('./txt/start.txt','utf-8');
        console.log(fileName);

        //2.并行读取两个文件
        const [data1,data2] = await Promise.all([
            fs.readFile(`./txt/${fileName}.txt`,'utf-8'),
            fs.readFile(`./txt/append.txt`,'utf-8')
        ]);
        console.log(data1);
        console.log(data2);
        //3.合并内容,写入文件
        await fs.writeFile('./txt/final.txt',`${data1}\n${data2}`,'utf8');
        console.log('文件成功写入!');
    }  catch (err) {
        console.log('发生了错误',err.message);
    }
}

processFiles();

这样从上到下看下来,是不是逻辑非常的清晰

相关推荐
西瓜太郎4995 小时前
API Key 轮换不该靠“瞬间替换”:用双 Key 灰度避免线上中断
node.js·api
星辰徐哥19 小时前
本地视频预览别只自己看:把Remotion动效项目发给客户远程验收
docker·ai·node.js·html·音视频·react·remotion
ID34610744201 天前
【课程设计】基于Spring Boot+Vue的校园共享无人机服务系统设计与实现-计算机毕设 附源码44219
javascript·vue.js·spring boot·python·node.js·php·课程设计
敲敲敲敲暴你脑袋1 天前
地图瓦片批量改色来啦!
node.js·gis·数据可视化
太子釢2 天前
AI 开发个人记账 App(服务端篇)
node.js·ai编程
用户64340495148512 天前
Elpis 项目构建工具与前端基建实践总结
node.js
FungLeo2 天前
成为全栈·Node 后端篇·后端测试策略:单元、集成与测试数据库
单元测试·node.js·集成测试·测试策略·成为全栈·测试数据库
FungLeo2 天前
成为全栈·Node 后端篇·评论内容安全:敏感词过滤、三态审核与级联删除
node.js·敏感词过滤·成为全栈·评论内容安全·评论审核·级联删除
FungLeo3 天前
成为全栈·Node 后端篇·阅读量防刷:去重、冷却与计数写分离
node.js·读写分离·数据去重·接口防刷·成为全栈·数据冷却
脉动数据行情13 天前
Node.js WebSocket 实现贵金属实时行情监听 伦敦金 / 伦敦银自动重连方案
websocket·node.js·vim