当前位置: 首页 > 科技观察

Vue源码思想在工作中的应用

时间:2023-03-15 00:39:08 科技观察

一、背景由于电脑CPU、内存等的限制,可以同时启动的任务数是有限的。例如,一台计算机可以执行5个异步任务,但目前有100个异步任务。任务是要执行的,那么这100个任务如何做到无间隔快速执行呢?2.问题解答第一次遇到这个问题的时候,我也是一头雾水。怎么处理???巧的是,最近学习了一些vue源码知识,那么是不是可以借鉴一下它的思路来解决这个问题呢?经过一步一步的分析,答案是肯定的。下面从解题思路、知识点和代码实现说说实现过程。2.1解题思路以上是整个流程图,其过程可以简化为以下步骤:将所有任务分成两组,任务组1指的是计算机可以并行执行的异步任务,任务组2指rest异步任务;将taskgroup1变为framelistening状态,即我们可以知道它什么时候发生变化;触发任务组1中的任务(任务不触发不执行);任务执行完成后,任务组2中的任务之一在帧监听状态下被填充到任务组1中;任务按照固定的数量不断执行,直到所有任务执行完毕。2.2知识点在Vue源码中,Vue2.x使用了Object.defineProperty()来实现frame监听数据;Vue3.0使用Proxy实现框架监听数据。本着紧跟潮流的态度和Proxy确实优秀的态度,在实现过程中也应用了Proxy。Proxy作为一个新的知识点,首先了解一下它的定义和用法。2.2.1定义Proxy中文意思是“代理”,就是在目标对象之间设置一层“拦截”,从而可以修改某些操作的默认行为。Proxy一共支持13种拦截操作:get、set、has、deleteProperty、ownKeys、getOwnPropertyDescriptor、defineProperty、preventExtensions、getPrototypeOf、isExtensible、setPrototypeOf、apply、construct。2.2.2简单使用functiontestProxy(obj){returnnewProxy(obj,{get:(target,key)=>{console.log(`我被get拦截器拦截了,拦截的属性是${key}`);},set:(target,key,value)=>{console.log(`我被set拦截器拦截了,拦截的属性为${key},新的值为${value}`);target[key]=value;}});}consttestObj={a:10};constproxy=testProxy(testObj);proxy.a=100;2.2.3详细用法详细用法可参考阮老师的《ECMAScript6介绍》逸风。2.3代码实现2.3.1定义两个任务队列首先定义两个任务队列,task1是一批要执行的任务,task2是后面加入的任务。consttask1=[1,2,3];consttask2=[4,5,6,7,8];2.3.2data的作用变成帧监听模块监听对应数组的变化,保证一直有一个一定长度的内容运行**@param{Array}initArr定长任务数组*@param{Function}callback对应回调函数*/functionwatcher(initArr,callback){constproxy=newProxy(initArr,{set(target,key,value,receiver){target[key]=value;callback(value,key,receiver);}});returnproxy;}2.3.3异步任务逻辑/***异步任务操作逻辑**@param{number}taskIndex异步任务个数*@param{number}index定长任务中当前任务个数*@param{Proxy}proxy代理实例*/functionasyncTask(taskIndex,index,proxy){console.log(`任务${taskIndex}在${index}索引处开始执行`);returnnewPromise(resolve=>{setTimeout(()=>{console.log(`${index}Task${taskIndex}处的索引被执行`);//当任务队列2中有任务时,进入队列替换任务1中执行的任务if(task2.length>0){proxy[index]=task2.shift();}},1000+2000*Math.random());});}2.3.4Mainfunctionconstproxy=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处的任务3完成执行5atindex1开始执行Task2atindex1完成执行Task6atindex1开始执行Task4atindex0完成执行Task7atindex0开始执行2Task5atindex完成执行Task2atindex2Task8startsto执行1.执行索引处的任务6。0.执行索引处的任务7。2.执行索引处的任务8,让我们一起讨论,一起进步。本文转载自微信公众号“前点线面”,可通过以下二维码关注。转载本文请联系前端点线面公众号。