文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Node.js中的Buffer和事件循环实例分析

2024-04-02 19:55

关注

这篇“Node.js中的Buffer和事件循环实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node.js中的Buffer和事件循环实例分析”文章吧。

Node.js中的Buffer和事件循环实例分析

Buffer 的使用


数据的二进制

Buffer和二进制

Buffer和字符串

const message = 'Hello'
// 使用new关键字创建buffer实例,但这种创建方法已经过期了
const buffer = new Buffer(message)
console.log(buffer); // <Buffer 48 65 6c 6c 6f>
console.log(buffer.toString()); // Hello

中文字符串的编解码

const message = '你好啊'
// 使用Buffer.from对我们的字符串进行解码
const buffer = Buffer.from(message)
console.log(buffer); // <Buffer e4 bd a0 e5 a5 bd e5 95 8a>
// buffer实例中有个toString方法可以对编码进行解码
console.log(buffer.toString()); // '你好啊'
const message = '你好啊'
const buffer = Buffer.from(message, 'utf16le')
console.log(buffer); // <Buffer 60 4f 7d 59 4a 55>
console.log(buffer.toString()); // `O}YJU

Buffer的其他创建方式

创建buffer的方式有很多,我们这里可以通过alloc的方式创建Buffer

// 其可以指定我们buffer的位数,比如这里传递进去的是8,那么创建出来的buffer就有8个元素,且每个元素对应的二进制数都是0
const buffer = Buffer.alloc(8)
console.log(buffer); // <Buffer 00 00 00 00 00 00 00 00>
// 赋值为十进制数字的话,buffer会帮我们转化为16进制数字再写入到对应的位置
buffer[0] = 88 
// 在js中,以0x开头的就表示为16进制的数字
buffer[1] = 0x88
console.log(buffer); // <Buffer 58 88 00 00 00 00 00 00>

Buffer和文件操作

1、文本文件

const fs = require('fs')
fs.readFile('./a.txt', (err, data) => {
  console.log(data); // <Buffer e5 93 88 e5 93 88>
})
const fs = require('fs')
// encoding表示解码所用的字符编码,编码默认为utf-8
fs.readFile('./a.txt', { encoding: 'utf-8' }, (err, data) => {
  console.log(data); // 哈哈
})
const fs = require('fs')
// 编码用的是utf16le字符编码,解码使用的是utf-8格式,肯定是解不是正确的内容的
fs.readFile('./a.txt', { encoding: 'utf16le' }, (err, data) => {
  console.log(data); // 鏥袓
})
// 以上代码和下面代码类似
const msg = '哈哈'
const buffer = Buffer.from(msg, 'utf-8')
console.log(buffer.toString('utf16le')); // 鏥袓

2、图片文件

const fs = require('fs')

fs.readFile('./logo.png', (err, data) => {
  console.log(data); // 打印出来的是图片文件对应的二进制编码
  
  // 我们还可以将图片编码写入到另一个文件当中,相当于我们将该图片拷贝了一份
  fs.writeFile('./bar.png', data, err => {
    console.log(err); 
  })
})
const sharp = require('sharp')

// 将logo.png这张图片裁剪成200x300后拷贝到文件bax.png中
sharp('./logo.png')
  .resize(200, 300)
  .toFile('./bax.png', (err, info) => {
    console.log(err);
  })

// 还可以将图片文件先转为buffer,然后在写入到文件中,也可以实现拷贝图片的目的
sharp('./logo.png')
  .resize(300, 300)
  .toBuffer()
  .then(data => {
    fs.writeFile('./baa.png', data, err => {
      console.log(err);
    })
  })

Buffer的创建过程

事件循环和异步IO


什么是事件循环?

Node.js中的Buffer和事件循环实例分析

进程和线程

进程和线程是操作系统中的两个概念:

听起来很抽象,我们直观一点解释:

再用一个形象的例子解释

多进程多线程开发

操作系统是如何做到同时让多个进程(边听歌、边写代码、边查阅资料)同时工作呢?

Node.js中的Buffer和事件循环实例分析

Node.js中的Buffer和事件循环实例分析

浏览器和JavaScript

JavaScript的执行过程

函数要被压入函数调用栈中后才会被执行,下面我们来分析下代码的执行过程

const message = 'Hello World'

console.log(message);

function sum(num1, num2) {
  return num1 + num2
}

function foo() {
  const result = sum(20, 30)
  console.log(result);
}

foo()

浏览器的事件循环

如果在执行JS代码的过程中,有异步操作呢?

那么,往setTimeout函数里面传入的函数(我们称之为timer函数),会在什么时候被执行呢?

为什么setTimeout不会阻塞代码的执行呢?就是因为浏览器里面维护了一个非常非常重要的东西——事件循环

当然事件队列中不一定只有一个事件,比如说在某个过程中用户点击了浏览器当中的某个按钮,我们可能对这个按钮的点击做了一个监听,对应了一个回调函数,那个回调函数也会被加入到我们的队列里面的,执行顺序按照它们在事件队列中的顺序执行。还有我们发送ajax请求的回调,也是加入到事件队列里面的

总结:其实事件循环是一个很简单的东西,它就是在某一个特殊的情况下,需要去执行某一个回调的时候,它就把提前保存好的回调塞入事件队列里面,事件循环再给它取出来放入到函数调用栈中

Node.js中的Buffer和事件循环实例分析

宏任务与微任务

但是事件循环中并非只维护一个队列,事实上是有两个队列,而且队列中的任务执行一定会等到所有的script都执行完毕后

那么事件循环对于两个队列的优先级是怎么样的呢?

面试题<一>

考点:main stciptsetTimeoutPromisethenqueueMicrotask

setTimeout(() => {
  console.log('set1');4
  new Promise(resolve => {
    resolve()
  }).then(resolve => {
    new Promise(resolve => {
      resolve()
    }).then(() => {
      console.log('then4');
    })
    console.log('then2');
  })
})

new Promise(resolve => {
  console.log('pr1');
  resolve()
}).then(() => {
  console.log('then1');
})

setTimeout(() => {
  console.log('set2');
})

console.log(2);

queueMicrotask(() => {
  console.log('queueMicrotask');
})

new Promise(resolve => {
  resolve()
}).then(() => {
  console.log('then3');
})

// pr1
// 2
// then1
// queueMicrotask
// then3
// set1
// then2
// then4
// set2

面试题<二>

考点:main scriptsetTimeoutPromisethenqueueMicrotaskawaitasync

知识补充:async、await是Promise的一个语法糖,在处理事件循环问题时

async function async1() {
  console.log('async1 start');
  await async2()
  console.log('async1 end');
}

async function async2() {
  console.log('async2');
}

console.log('script start');

setTimeout(() => {
  console.log('setTimeout');
}, 0)

async1()

new Promise(resolve => {
  console.log('promise1');
  resolve()
}).then(() => {
  console.log('promise2');
})

console.log('script end');

// script start
// async1 start
// async2
// promise1
// script end
// async1 end
// promise2
// setTimeout

以上就是关于“Node.js中的Buffer和事件循环实例分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯