「源码共读」第32期 | yocto-queue 队列 链表

129 阅读3分钟

源码解析

源码地址

下载到本地后打开

该项目全部目录

image.png

package.json 中得知 index.js 为索引文件

image.png

解读源码

image.png

class Node {
	value;
	next;
        // 每次调用创建数据节点并创建俩个属性
	constructor(value) {
		this.value = value;
	}
}
export default class Queue {
	#head;
	#tail;
	#size;
        
        // 每次调用先进行清除链表
	constructor() {
		this.clear();
	}
        // 排队
	enqueue(value) {
                // 调用时 先创建一个数据节点 把值传递给 数据节点
		const node = new Node(value);
                // 如果当前队列有头部
		if (this.#head) {
                   // 把当前的尾部下一个节点设置为 当前节点
	           this.#tail.next = node;
                   // 把尾部设置为当前节点
	           this.#tail = node;
                // 如果没有头部 默认肯定为 undefined
		} else {
                // 把头部和尾部都设置为当前节点数据
	           this.#head = node;
	           this.#tail = node;
		}
                // 排完队后大小加一
		this.#size++;
	}
        // 出列
	dequeue() {
                // 从队列的头部获取节点
		const current = this.#head;
                // 如果当前没有节点的话 证明这个队列为空 就什么都不返回
		if (!current) {
			return;
		}
                // 把队列头部数据 设置为头部的下一个
		this.#head = this.#head.next;
                // 队列大小减一
		this.#size--;
                // 返回当前出列后的数据,以备有其他用处
		return current.value;
	}
        // 清除队列 把各值都设为空值
	clear() {
		this.#head = undefined;
		this.#tail = undefined;
		this.#size = 0;
	}
        // 通过 get 语法糖 设置为可以直接获取的值 返回 当前队列的长度
	get size() {
		return this.#size;
	}
        // 设置遍历器并调整为 generate 函数
	* [Symbol.iterator]() {
                // 把头部设为当前数据
		let current = this.#head;
                // 只要有数据就一直执行
		while (current) {
                        // 拿到当前数据并把当前的变量改为下一个数据
			yield current.value;
			current = current.next;
		}
	}
}

解析半天先解释几个关键词.

  • get 关键字
  • Symbol.iterator
  • generator 函数 (* yield)

get 关键字

mdn getter

get 语法将对象属性绑定到查询该属性时将被调用的函数。

该关键会通过语法糖直接调用 getter 函数 从而在开发者调用是不需要调用函数.

Symbol.iterator

mdn Symbol.iterator

Symbol.iterator 为每一个对象定义了默认的迭代器。该迭代器可以被 for...of 循环使用。

简单解释就是 可以直接使用 forof 来循环遍历的迭代器 但是内部要迭代的数据和操作可以自定义。

generator 函数

mdn generator函数

Generator 对象由生成器函数返回并且它符合可迭代协议迭代器协议

构造函数

Generator 构造函数并不是全局可用。Generator 的实例必须从生成器函数返回:

function* generator() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = generator(); // "Generator { }"

console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3

好了 陌生的关键字以及简单了解了使用以及知道是什么了,下面可以调试了。

调试

把下载下来的源码项目先 安装下 包

npm install

package.json 找一下测试脚本

image.png

在项目目录中找 .test. 或者 test 的文件

image.png

找到后可以优先调用下看看工具是否可用

npm run test

image.png

ok,接下来可以选择自己写一段 测试方法.

test("test", (t) => {
	// 创建队列
	const queue = new Queue();
	// 检验 入队
	queue.enqueue("张三");
	queue.enqueue("李四");
	// 校验当前队列长度是否一致
	t.is(queue.size, 2);
	// 校验出队数据是否返回相同 和 功能
	t.deepEqual(queue.dequeue(), "张三");
	t.is(queue.size, 1);
	// 校验迭代器
	t.deepEqual([...queue], ["李四"]);
	// 校验clear函数
	queue.clear();
	t.deepEqual(queue.size, 0);
});

image.png

测试的调用也是没问题的。

结语

可以阅读他人之长处,阅取他人之他人之精髓,方可进步。