【若川视野 x 源码共读】31-35 期 总结

154 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

简单讲p-limit、yocto-queue、arrify、tdesign-vue 如何初始化组件、vite-pretty-lint

31 p-limit

我:www.yuque.com/ruochuan12/…

川:www.yuque.com/ruochuan12/…

作用

用来对前端并发请求进行控制的

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

我:www.yuque.com/ruochuan12/…

川:www.yuque.com/ruochuan12/…

作用

链表,入列和出列api。相对于数组pushshift,但是性能更好,当数组 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 转数组

我:www.yuque.com/ruochuan12/…

川:www.yuque.com/ruochuan12/…

作用

将值转为数组,

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 初始化组件

我:www.yuque.com/ruochuan12/…

川:www.yuque.com/ruochuan12/…

作用

  • 新增组件: npm run init [组件名]
  • 删除组件:npm run init [组件名] del

原理

.要有个创建组件对应的文件列表,还有相应的模板,创建时,遍历创建,还需要导入

渲染模板时,用loadsh_.template 方法

有子库是其他仓库时,要 git submodule init && git submodule update

35 为 vite 项目自动添加 eslint 和 prettier

我:www.yuque.com/ruochuan12/…

川:www.yuque.com/ruochuan12/…

作用

用命令去安装和初始化vite项目的 ESLintPrettier

npm init vite-pretty-lint
从弹出的选项 选择 项目类型和包管理器 vue 、 npm

效果:

多出.prettierrc.json.eslintrc.json等文件,里面有常见的配置,具体参考下面的链接

github.com/lxchuan12/v…

原理

询问项目类型和包管理器

通过项目类型拿到对应模板

构建安装依赖的命令

确定vite配置文件,修改

执行安装依赖

写入配置