关于前端:Vue源码思想在工作中的应用

一、背景

因为电脑CPU、内存等的限度,可能同时启动的工作数有肯定限度,例如一台电脑可能执行5个异步工作,然而目前有100个异步工作要执行,那么如何让这100个工作无距离的疾速执行结束呢?

二、问题解答

刚遇到这个问题的时候,也是出于懵逼状态,怎么解决呢???碰巧的是近期学习了一些Vue的源码常识,那么是不是能够借鉴其思维来解决遇到的这个难题呢?通过一步步剖析,确定答案是必定的。上面从解题思路、知识点及代码实现来聊一聊实现过程。

2.1 解题思路

上述是整个流程图,其流程可简化为以下几个步骤:

  1. 将所有工作分为两组,工作组1指的是电脑能够并行执行的异步工作,工作组2指的是其余的异步工作;
  2. 将工作组1变为可帧听状态,即其发生变化时咱们可能晓得;
  3. 将工作组1中的工作触发(不触发工作不会执行);
  4. 某一工作执行结束后,将工作组2中的一个工作填充到可帧听状态的工作组1中;
  5. 工作依照固定数量一直执行,直到所有工作执行结束。

    2.2 知识点

    在Vue源码中,Vue2.x应用Object.defineProperty()实现对数据的帧听;Vue3.0应用Proxy实现对数据的帧听。本着赶时髦和Proxy的确优良的态度,在实现过程中也利用了Proxy。Proxy作为一个新的知识点,先理解一下其定义及应用办法。

    2.2.1 定义

    Proxy中文意思是“代理”,是在指标对象之间架设一层“拦挡”,从而能够批改某些操作的默认行为。Proxy共反对十三种拦挡操作:get、set、has、deleteProperty、ownKeys、getOwnPropertyDescriptor、defineProperty、preventExtensions、getPrototypeOf、isExtensible、setPrototypeOf、apply、construct。

    2.2.2 简略应用

    function testProxy(obj) {
     return new Proxy(obj, {
         get: (target, key) => {
             console.log(`我被get拦截器拦挡了,拦挡的属性是${key}`);
         },
         set: (target, key, value) => {
             console.log(`我被set拦截器拦挡了,拦挡的属性是${key}, 新值是${value}`);
             target[key] = value;
         }
     });
    }
    
    const testObj = {
     a: 10
    };
    const proxy = testProxy(testObj);
    
    proxy.a = 100;

    2.2.3 具体应用

    具体用法能够参考阮一峰大佬的“ECMAScript 6入门”。

    2.3 代码实现

    2.3.1 定义两个工作队列

    首先定义两个工作队列,task1为开始执行的一批工作,task2中为后续增加进去的工作。

    const task1 = [1, 2, 3];
    const task2 = [4, 5, 6, 7, 8];

    2.3.2 数据变为可帧听的函数

    利用Proxy将数据变为可帧听状态

    /**
     * 监听模块,监听对应数组的变动,保障其始终有肯定长度的内容在运行
     *
     * @param {Array} initArr 定长工作的数组
     * @param {Function} callback 对应的回调函数
     */
    function watcher(initArr, callback) {
     const proxy = new Proxy(initArr, {
         set(target, key, value, receiver) {
             target[key] = value;
             callback(value, key, receiver);
         }
     });
     return proxy;
    }

    2.3.3 异步工作逻辑

    /**
     * 异步工作的运行逻辑
     *
     * @param {number} taskIndex 异步工作的序号
     * @param {number} index 当前任务在定长工作的序号
     * @param {Proxy} proxy Proxy实例
     */
    function asyncTask(taskIndex, index, proxy) {
     console.log(`${index}索引处的工作${taskIndex}开始执行`);
     return new Promise(resolve => {
         setTimeout(() => {
             console.log(`${index}索引处的工作${taskIndex}执行结束`);
             // 当工作队列2中还有工作时,进入队列替换工作1中执行完的工作
             if (task2.length > 0) {
                 proxy[index] = task2.shift();
             }
         }, 1000 + 2000 * Math.random());
     });
    }

    2.3.4 主函数

     const proxy = watcher(task1, asyncTask);
     task1.forEach((taskIndex, index) => asyncTask(taskIndex, index, proxy));
    }
    
    2.3.5 执行后果

    通过后果能够看到,当一个工作实现时立即将有一个新的工作进入。

    0索引处的工作1开始执行
    1索引处的工作2开始执行
    2索引处的工作3开始执行
    0索引处的工作1执行结束
    0索引处的工作4开始执行
    2索引处的工作3执行结束
    2索引处的工作5开始执行
    1索引处的工作2执行结束
    1索引处的工作6开始执行
    0索引处的工作4执行结束
    0索引处的工作7开始执行
    2索引处的工作5执行结束
    2索引处的工作8开始执行
    1索引处的工作6执行结束
    0索引处的工作7执行结束
    2索引处的工作8执行结束

    三、探讨

    针对此类问题的解决形式,各位大佬有新的思路与办法欢送留言,咱们一起探讨,共同进步。

1.如果感觉这篇文章还不错,来个分享、点赞吧,让更多的人也看到

2.关注公众号执鸢者,支付学习材料(前端“多兵种”材料),定期为你推送原创深度好文

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理