携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
- 本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。
简单讲p-limit、yocto-queue、arrify、tdesign-vue 如何初始化组件、vite-pretty-lint
31 p-limit
作用
用来对前端并发请求进行控制的
import pLimit from 'p-limit';
//设置并发限制
const limit = pLimit(1);
//用limit包裹 异步请求
const input = [
limit(() => fetchSomething('foo')),
limit(() => fetchSomething('bar')),
limit(() => doSomething())
];
// Only one promise is run at once
const result = await Promise.all(input);
console.log(result);
原理
1 传入并发限制最大数,返回个方法供 加异步函数
2 使用数组 组装 要限制并发的任务们 ,通过上面的方法传入 异步函数
3 传入后 同步存储到队列中,异步执行异步函数,异步执行时判断限制数量去执行
4 使用
promise.all包裹上面的 数组队列,获取结果
export default function pLimit(concurrency) {
const queue = new Queue();
let activeCount = 0;
// 传入promise执行函数
const enqueue = (fn, resolve, args) => {
// 以上面的例子举例,这里先推三个 run 任务进队里,同步加入
queue.enqueue(run.bind(undefined, fn, resolve, args));
//这里是异步任务,所以会在上面所有limit任务进队才执行。
(async () => {
// activeCount:当前执行任务数,concurrency:并发限制,队列有任务
if (activeCount < concurrency && queue.size > 0) {
// 我一开始以为是队列连续推出两个,直到我调试才知道他是队列推出一个去执行,接着看run
queue.dequeue()();
}
})();
};
//当前执行任务小于并发限制数量时,去执行
const run = async (fn, resolve, args) => {
//每执行一次,当前执行任务加一
activeCount++;
// 执行fn。
const result = (async () => fn(...args))();
// 得到结果要返回
resolve(result);
try {
await result;
} catch {}
// 执行完 后 走next
next();
};
// 执行完后 推出队列任务再执行
const next = () => {
// 执行完 任务 后,当前执行任务-1
activeCount--;
// 有任务结束去掉了,并发限制肯定没满,看看能不能加
if (queue.size > 0) {
queue.dequeue()();
}
};
const generator = (fn, ...args) => new Promise(resolve => {
//这里的fn就是传入的异步请求函数。转到enqueue
enqueue(fn, resolve, args);
});
return generator;
}
32 yocto-queue
作用
链表,入列和出列api。相对于数组push和shift,但是性能更好,当数组 shift 时,所有元素都要往后挪一位
import Queue from 'yocto-queue';
const queue = new Queue();
queue.enqueue('🦄');
queue.enqueue('🌈');
console.log(queue.size);
//=> 2
console.log(...queue);
//=> '🦄 🌈'
console.log(queue.dequeue());
//=> '🦄'
console.log(queue.dequeue());
//=> '🌈'
原理
每一个值都是一个节点,有头节点和尾节点
class Node { value; next; constructor(value) { this.value = value; } }当入栈时,构造节点,拼接尾节点
出栈时,拿出头节点,头节点后移一位
学
// 定义了迭代器,使得链表允许遍历,
* [Symbol.iterator]() {
let current = this.#head;
while (current) {
// yield 通过 next 继续执行,或者for-of,解构。
yield current.value;
current = current.next;
}
}
33 arrify 转数组
作用
将值转为数组,
import arrify from 'arrify';
arrify('🦄');
//=> ['🦄']
arrify(['🦄']);
//=> ['🦄']
arrify(new Set(['🦄']));
//=> ['🦄']
arrify(null);
//=> []
arrify(undefined);
//=> []
arrify(new Map([['a',2]]));
//=> [[a,2]]
原理
空返回 空数组
数组直接返回
字符返回 [字符]
有迭代器 迭代取值进数组返回
其他情况返回 [val],包括对象
export default function arrify(value) {
if (value === null || value === undefined) {
return [];
}
if (Array.isArray(value)) {
return value;
}
if (typeof value === 'string') {
return [value];
}
// string也有 Symbol.iterator,所以要先判断 string。
// map、set、argument
if (typeof value[Symbol.iterator] === 'function') {
return [...value];
}
return [value];
}
34 tdesign-vue 初始化组件
作用
- 新增组件: npm run init [组件名]
- 删除组件:npm run init [组件名] del
原理
.要有个创建组件对应的文件列表,还有相应的模板,创建时,遍历创建,还需要导入
学
渲染模板时,用
loadsh的_.template方法有子库是其他仓库时,要
git submodule init && git submodule update
35 为 vite 项目自动添加 eslint 和 prettier
作用
用命令去安装和初始化vite项目的 ESLint和Prettier
npm init vite-pretty-lint
从弹出的选项 选择 项目类型和包管理器 vue 、 npm
效果:
多出.prettierrc.json和 .eslintrc.json等文件,里面有常见的配置,具体参考下面的链接
原理
询问项目类型和包管理器
通过项目类型拿到对应模板
构建安装依赖的命令
确定vite配置文件,修改
执行安装依赖
写入配置