粉丝9279获赞3.1万


大家好,今天这节课主要想跟大家分享拍摄当中的定时任务。定时任务在企业开发中的场景非常多,比如定时更新微信的 需要两小时更新一次,或者商城商品定时上线,还有 定时检测后台服务是否存活等等。那么今天就给大家详细讲解一下定时任务的使用方法。定时任务分为很多种,我这里列举了常用的五种方式,第一种 使用县城睡眠函数实力的方法。第二种使用县城定时器胎毛。第三种使用史该丘的模块。 第四种是使用任务框架 ap 是该求的,最后一种 是分布式异步框架 siri。 那么现在先介绍第一种 使用现成睡眠函数实力的方法,这个方法类似加瓦里边的实力的方法。我们看一下下面这张代码。 首先我们要导入戴的太母裤和太母两个模块,我们在组函数里就用一个方法叫胎母,它是可这个函数 会每十秒钟打印当前的时间,使用实力谱加死循环的方式非常简单和粗暴,这种方法它能够固定间隔时间的任务,如果泰姆的它是可函数 之后还有一些操作,我们还使用死循环加主摄线程,这会使得他按摩他此刻一直会占用 cpu 的资源,导致后续的操作无法 执行。也就是说当我们执行实力普方法的时候,如果当时还在睡眠当中, cpu 这个时候会一直占用资源,直到休眠完成,他是 主色现成的,所以这种方式不建议使用。给大家演示一下这段代码,我们在工程目录里新建了太猛开始个一点希望呀, 我们把这个代码执行一下, 现在在控制台已经输出了当前的年月日时分秒, 每十秒钟打印当前时间。这种现成函数实力谱加死循环的方式简单粗暴, 他会一直占用 cpu 的资源,使用起来要慎重。好的,这是拍摄当中第一种定时任务的方法。

大家好,今天给大家介绍一个组件,就是 background worker, 我们使用这个组件可以非常轻松的制作一个异步多线程的程序。好,我们首先将这个组件拖到界面上, 基面上是看不见的,因为它是一个主键,我们在下方可以找到它。当然我们也可以直接在窗体的代码当中溜一个这个类的对象啊,效果是一样的。 当前在我们窗底上呢,有一个进度条,有一个开始的按钮,还有一个取消的按钮, 也就说我们今天要写的这个程序呢,就是说使用这个组件让他在后台运行一个线程,不影响我们 ui 的一个线程。同时呢我们可以启动 它,也可以终止它,它在运行的过程当中,我们可以显示一些它的进度,还有它工作当中的一些状态信息。 为了方便大家理解,我给大家绘制了一张 cad 的图纸,我们来看一下, 通过它呢,我们可以很快地理解这个组件的功能,我们可以把这个 background worker 想象成一个盒子,在这个盒子里面呢,我们 可以放上我们的一个处理代码,他是在单独的一个县城当中来执行这些处理代码的,然后我们这个盒子上面有个 开关,当我们按下这个开关的时候,那么这个处理代码就会进行他的处理。红色的按钮呢,我们可以终止他,有的他没有执行完,我们也可以终止他,我们可以在开始的时候给他一些原材料,也就是参数。 我们在结束的时候呢,可以输出一个处理的最终结果,就 result。 在他运行过程当中呢,我们可以看到他的运行的状态,也说我们这个盒子可以非常方便的来管理一个翼部的一个线层, 我们不仅仅是直接启动了就不管他了,我们可以看到他中间产生的一些状态数据,可以启动,可以终止,可以给 参数,可以得到结果。好,我们来具体写下代码,我们打开代码界面,第一步我们要对这个组件进些基本的属性设置 第一个属性,它的意思就是说我们的进度报告是否允许发送,也就是我们这个图纸里面的这里, 在我们这个县城运行当中,是否将他的状态信息发送出来,当然我们这里是要处的。 第二个属性呢,就是我们的 consulation, 就是我们的取消,是否允许取消?如果你在 这里设为 force 的话,那么我们这里这个按钮呢相当于按下去也没有作用,所以我们这里同样的设为处。 当这两个状态设置了以后呢,我们需要做的下件事情就是设置这个事件处理程序,你说我这个盒子里面到底要运行什么样的代码要给他啊?他有一个 do work 这样一个事件, 我们选中这个主键,然后在这边四键窗口里面找到他的四键,第一个双击 好,我们现在将代码已经拷贝到这里面来了,也就是说我现在这个多线程启动 以后要做什么事情,我把它放在里面了,我们再来设置一下它的启动代码, 也就是我们这个按按钮的这个单击四键,我们双击创建了这样一个方法。然后呢我们选择一下, 我们来讲一下这段代码,这里面呢就是我们的这个组件的一个启动的方法, 他有两两个存在,就是一个是没有参数的,一个是有参数的,就是我启动这个线程可以在这里面放一个参数,也可以不放参数。 但是 在我们启动之前呢,这里要进行一个检查,我们这个组件当前是否忙,如果不忙的情况下,我们才能够启动他,比如说他已经在执行一个县城的时候,那么你是不能启动他的。 好,这是我们的启动代码,非常简单,那么我们再来做一个取消的代码,同样的是这个按钮,我们双击 也是非常简单的一个方法就可以取消现成 就是看守方法啊。当然呢我们看到这个启动和取消呢,它都是一个翼步的,都带了一个 isonk 这样一个后缀。 在这个取消的方法前面呢,我们必须要进行一个检测,就是我这个组件是否允许,是否支持取消这个命令,哎,我们在上面已经设置过了,是允许 取消,所以我们这个时候才能真正的取消。 好,现在呢我们来研究一下它最终执行的这个代码,也就说在这里呢,我们已经点下这个按钮的时候,我们已经可以启动它了, 那么就进入了这个线层里面,这个线层呢就不会影响我们的 ui 啊,通过我们的这个 thunder 对象呢,我们 可以得到我们的这个组件, 也就是说这个方法里面的所有内容,它会另起一个线程,而不是在我们的 u i 线程里面运行, 同时我们还可以通过这个参数一可以得到我们刚刚传给这个线程的一个参数 argument, 就通过这个我们就可以得到它的参数,当我们这里面没有使用,所以我最后直接给返回值了。 在这个方法里面呢,我们是做的是一个循环啊,我们 i 从一到一百也说循环一百次,当然我们这个县城可以不是循环的啊,我们这里, 嗯,做一个循环的更好理解一点,比如说我们要复制一百个文件,那么我们一一个一个文件的复制,复制一个,那么我们任务就完成了百分之一, 我们就可以在这个里面呢给他发送一个进度报告,然后把这个一传给他,复制了十个文件,我们就传个十给他, 我们的进度就完成了百分之十,一百个文件的时候,我们就百分之百啊,当然你可以说你不是一百个文件,你是两百个,那么我们这个时候可以对这个 i 进行一个处理,那么就最终也可以得到它的进度。 也就是说在这个方法里面我们使用了 report progress, 就是提交一个进度报告,这个方法呢非常重要 啊,他会引发一个事件,就是我们马上要写的一个代码,当我们提交一个报告的时候,就相当于是我们在这个地方提交了一个状态数据过来, 那么我们这个线程外面的线程,就是我们 ui 线程就可以搜到这个数据,将它显示到界面上。 我们双击创建这样一个事件处理代码, 就是 progress change 这样一个,就是我们进度变化这样一个处理事件,同样的我们把代码复制过来。 嗯,这里要给大家说一下我们这个事件处理程序,它是义不调用的,也就是说它和引发事件的代码不在同一个线程上。 progress 清级的事件处理代码,它和创建 background worker 的线程是同一个,也就是 ui 线程上执行的 同时,他还传递了一个数据过来,这其实就是跨线层访问空间,跨线层传递数据的一种方式,而且我们不需要做任何事情,直接就可以使用。比如我们在这里面我们使用了这个 progress 八这样一个就是进度条它的 y 六,我们可以设置它为我们参数里面的这个数值,这个数 值其实就是我们这里传过来的这个 i, 当我这里运行了 百分之多少的时候,这个 i 就传过来了,传过来以后我设置这个进度条的这个 value, 那么我们就可以显示到界面上,看到我整个任务完成的进度。同时呢我们可以设置这个 label 的 text 属性来显示它的百分比进度, 可以来看一下效果, 当我们点开始的时候,这个进度条就可以从百分之一一直走到百分之百, 这个地方呢也会显示它的进度,它是一个跨线层的事件, 通过这个事件传递了数据给我们的 ui 县城,我们不需要做其他的任何处理,不用写一个 in work 这样来处理。 好,我们再来看一下如何取消这个现成的,就是我们的 ctrl 怎么来执行的, 我们这里虽然有一个 ctrl 这样一个方法,但是我们如果不做其他的处理,你点了以后它其实不会有反应的,我们必须要在我们的这个 县城里面对他进行一个处理,就是这个地方也说在这个循环里面我执行百分之一,我要来检查一下其他的县城有没有取消,我们这个县城就这么的 开始类型这样一个属性啊。在这里面如果是处就代表说其他的县城当中执行了一个看守这样一个方法来取消。如果是取消的话,我就需要进行一个设置,然后终止我们这个循环处理 啊,这个就是我们的取消的一个处理啊。在上一个视频当中呢,有朋友就是在问,就是说能不能够,就是说不用这样循环的,不断的 这样来取消了,就直接给他一个命令,然后他就取消掉了,那这种属于强制的取消啊,是非常不好的,哪怕我们这个程序不是这样循环处理,不是一到一百的这样循环,那么你是一个线性的代码啊,你 走几步你要判断一下啊,外面是否取消了,走几步我们再判断一下外面是否取消了,一样的,我们必须要时刻去监视这个值,如果取消了,那么我们就要结束我们的代码执行,这才是正规的规范的一种取消的方式。 在这里要给大家说一个事情,就是说这个地方我们使用的 thread 来休眠呢这样一个时间点, 嗯,实际编码当中这个代码肯定是要被替换掉的,你说这一块才是我们 真正真正要做事情的这个代码模块。比如说我在这个地方我循环的去检测我机器的设备,比如我的 prc 啊啊,各种各样的机器,它的数据,温度啊、湿 度啊等等等等这些数据当我监测到以后,我就可以通过这个进度报告把它传递给我们的 ui 县城,把它显示出来,这是我们工作当中经常会用到的技能。 那这里我们做了一个简单的示范,就说在这里我们可以取消它, 你说这个方法它有一个存在,可以有两个参数,第一个是它的完成度,就是百分比。第二个呢是我们的这个用户的数据,我们可以把我们的这些状态信息包装成一个对象, 或者包装成一个 top, 然后直接传过去。在我们的这 这个事件处理当中,我们可以接收,比如这里 我们可以在这里把这个 data 接收到,然后可以显示出来。 啊,这一点就非常好用,就是我们的跨线层传递信息传递状态。 当然我们还有一个事件要进行处理,现场所有的任务都完成以后,我们要对最终要进行一个处理,那这个时候我们还可以来写 选中这个,然后在这个事件处理里面还有最后一个事件,我们双击,哎,这个就是一个 company 的这样一个事件,也就说完成状态。 如果我整个县城所有的事情都做完了,也就是我们这个图形里面的做完了以后,我这个地方要得到一些什么样的结果进行一个处理 啊?在这个代码当中我们会有三种状态进行一个判断,第一种呢就说用户是否取消了,如果取消了,我们会显示一个取消的一个状态, 如果说在这个线程执行当中发生了错误,那么我们可以有一个错误的提示, 那否则嘞?第三种就是我们完整的完成了这个任务,这个时候我们可以显示到我们的最终处理结果啊,就是 result, 通过这个参数的 result 属性呢,可以得到我们最终的结果,当这个结果哪里来的这个结果?就是在我们这个方法里面,最后的时候付给这个 result, 也就是说我们可以通过启动这里传一个参数啊,当然也是 object 的类型的话,我们可以包装一个什么样的类型传给他都可以,这是启动代码传一个参数给我们的处理线程, 处理线层处理的时候,我们可以把中间状态输出给我们的界面, 处理完了以后我们还可以输出我们最终的结果。同样呢,它也是一个 object 的类型,我们可以包装成各种各样的类型传递给 他,然后,哎,在我们的完成的这样一个事件里面获得这个结果进行一个相应的处理啊。好,这个就是我们的这个组件的一个基本介绍。我们最终再来看一下这个结果, 点击开始,在这个地方呢就显示的是一个我们的中间的一个状态啊,这里没有变化是因为我们直接传递的是一个固定的数据, 如果是我是采采集的电压、温度、湿度等等这些,那么他肯定就是一个变化的数据,我们可以动态的展示出来。 这里呢就是运行到最后的时候,我们将结果显示出来了,因为我们的最后的代码就是显示我们的结果, read out, okay, 好,今天就讲到这里。


哈喽,大家好,我是空挡发行。在 spring 营养中,如果想让一个方法一步执行,我们通常通过 think 注解来实现。它会使用 spring 默认的现成尺。在这段代码中,我们演示了如何使用自定义现成尺来执行一步任务。我们定义一个类型为 sered potask execute 的令,然后配置它的现成数、超时、时间、 等待对列等参数。在 my asink service 中,使用 asink 注解来一步执行 perform asink task 方法,并指定了运行它的现成池,这将确保该方法在前面定义的 asink execute 的现成池中执行。在生产的项目中, 一般都要求使用自定义的线绳尺,以更好的控制衣补任务的执行。看到这里了,给点个赞呗,私聊拿原码。

兄弟们,这期我们来思考一个问题,如何解决非业务类和业务类的操作分离实现,从而提高系统的性能。我们来看看若一是如何实现的。在 size login service 和日制操作类 log aspect 中 可以看到这样奇怪的异形代码是用来做什么用的呢?仔细分析后,原来是用异部的方法实现用户登录、退出及用户操作业务日志的数据库写入。这样做有什么好处呢?其好处是将非业务类的处理交给异部现成池处理, 从而提高主线成处理业务的能力。举个也许不是太恰当的例子,不分离的方式就像独臂大侠,所有的动作都只能一只手来完成。而分离的方式就像双臂大侠右手承接及处理业务操作, 左手处理非业务类的操作,例如写日志,这样右手就具备更强的业务处理能力了。

哈喽,各位观众朋友们大家好,今天我们来学习这个维于三的第十八章,这个一部组件跟这个代码分包和这个 surps 这一张呢比较重要,会涉及到一些这个性能优化的问题,这个性能优化的问题呢,咱们面试的时候经常会问, ok, 那我们来先演示一下啊。 首先我们给我们这个项目呢来打一个包,我们通过 mpm 装 beild 对执行这个打包秘密,他会帮我去打包,因为浏览其实不认识这个点微微文件的,所以说我们打包给他编一下,大家可以稍等一下。 ok, 那打完包之后呢,他会给我们生成一个 des 头的一个目录,就是一个这个,然后里边有这个 index html, 这个 这一套的杰森是我自己定义的,这个大家大家不用管。然后还有一个这个 assassin, assass 里边呢有这个 index 的这个 gs 跟这个 window 的 gs, 那这两个是什么意思呢? 温在了这解释呢,他就是把一些第三方的模块包呢,都会给你打到这个里边,比如说这个 vu e 啊,还有这个 exs 啊, xo 啊, omuy 啊,这些都会给你打到这个包里边。那风就是放一些第三方的依赖库, 这个 index j s 呢,这个里边是放我们这些主逻辑的,比如说我们这个 app 威欧啊,还有这些康康泰克的,还有点美女啊,这些组建呢,都会打到这个 index gs 里面,当然我们就是现实开发中的这个组建的,肯定是有成百上千个,就是有好多好多,那导致呢?这个 包括这个非常的大,可能有三十兆,甚至是这个四十兆, ok, 当用户去访问我们这个网页的时候呢,服务器会加载我们这个 index stm, 然后我们可以看到 加载完之后他会发一个这个链接呢,然后再去加载我们这个音带子的 gs, 加载这个 gs 包呢,他有三十招甚至四十招这么大,然后用户呢就要去那里等,这个过程是非常漫长的,然后呢就会有一个白屏的时间去在那等,所以说面试的时候呢,经常会问,就是这个白屏这个你去怎么去优化这个, 那我们就可以使用这个一部组件呢去优化这个东西, ok, 咱们来先演示一下,首先我在这个 ctrl 的下面呢,我新建一个文件,我叫 a, 然后给他建一个 ins, 我给我给他出示范一下。三,我随便写点东西能 tice, 然后我们还是在老地方这个 ctrl 里边去录他 input a frog 这个第二杠,第二杠 compart 是下面这个 a, 下面这个 indec, 然后我们使用的时候还是直接这样子去使用。 ok, 这个就是普通的去引路一个土件,你可以看一下啊, tas 没有问题,但是你这样引路的话,他还是会给你把这个包呢打到这个 index w 并不会给你拆分出来,这时候我们就要改写成这种 动态组件,呃,不是动态组件,一部组件,那我们改一下。首先我在这个 party 下面呢建了一个德特的阶层, 用这一段东西呢来模拟这个后台的接口啊,是一个数组,然后里边有四个对象,分别是冰蹲、蹲,一二三四 啊,这里边数据大家都自己定义,这是我随便建了一个模拟一下, ok, 然后我们在 a 这个组建里边呢,我们要封装一个这个找接口的工具,比较 sover, 点 ts, ok, 首先我们先定义一下这个类型, 这个 nail 连 ps 出来,然后有一个 nail 是一个 string, ok, 然后找出一个函数,一个 pose, 一个 x, ok, 然后这个一万以后我们可以穿过来,他是一个这样的 发挥一个 promise, 我们会用到这个瑞拉 ok, 这时候我们就要呃这个初刷这个 x h r, 你有一个叉 m l a t t p request, 用这个的去帮我们去调这个接口,它的类型就是叉 m l a t t p request ok, 这时候呢需要一个 open oppo 的,它第一个参数是我们解决的方式和我们房屋这个本地人,我们就使用这个 get, 那第二个参数是一个 url, ok, 比如说我们没有数据呢,给它传输我们可以剩的一个 no, ok, 他还有一个函数叫这个 x h r 点 unready c 的称之,就是每一个称之,每个扣的变化呢,他都会。 所以说在这个函数里边,我们可以判断 x h r 点 ready state 等于等于这个四,这个 ready state 一共是零一二三四五个步骤,大家可以具体去看一下,就是四呢,就代表最终完成了, ok, 然后 x h r 的这个 do 死为二百,二百的话就是证明这个接口是正常的,那这时候你就可以去返回了, 浪一个什么 x h r 点 response text, 对,这是返回的是一个文本,我不需要这个文本,我们需要把它转成这种,节省点 pass, 你让他返回这个阶层格式,不然他返回这是一堆字串,所以说这时候我们需要转一下,那这样子就没稳定,然后我们需要叮一下 返回的值,就是这个 promise, 它是一个范形,是一个 nameless 类型的一个数字啊,这样 ok, 这个简单的接口我们就分装完成了,然后我们在这个页面呢去使用一下,那么首先就要引入 inpot 这个 x for all 这个点杠 soda ts, ok, 然后在这个三十二步语法堂里面呢,我们直接是可以使用这个, 这个呃 over 呢,一般他是需要配合这个呃性格去使用的啊,在语法堂里面是不需要的,直接可以用这个。但是你如果自定义这个函数的话,你还是需要,比如说 cose 的一个 a 一个这个函数, 你如果自定义还是不写有性格的话,他是会有问题的,你还是需要自己写,但这个语法堂的话就直接可以在里边去使用了 啊, ok, 然后我们这个 ov 的一个 xoxo, 他一个意外,然后是当前目录下面这个 dee, 他这结实,那么需要请求这个结实文件 他返回的,我们把它已经定了,返回一个 promise, 所以说我们直接点认一下啊,这个不需要点赞, 因为我们是 o v 特, o v 特的话他会帮我们去读这个点子里边东西,所以说我们直接落一下 least 就可以了, 然后我们把这个给他延迟一下, set them out, 给他两秒钟之后去返回, ok, 然后我们再看一下页面刷新,等两秒钟, ok, 已经发挥了,在十二号就是在这,那完全没有问题,那这个呢?已经变成一个一部组件了,然后我们这是只是在子组件里边改一下,然后我们这个副组件呢,它里边也要改, 我们把这个数据你可以放到这个页面上,可以搞一个维纳 fo, 然后他会帮我们提示他已经知道这个爱他们有什么,比如说直接点内,因为我们刚才已经定好这个类型了,所以说 ts 跟这个 v v 三配合起来还是挺好用的,要不要刷新一样 啊?这时候不展示,这时候不展示其实是对的,因为什么呢?因为这时候我们已经把它变成一个一部组件了,我们这个副组件还没有改呢,我们找一下我们这个副组件, 对,改成异步组建呢,就不能用这种方式去引入了,那么怎么改呢?我们要这么改 const 一个 a 等于一个什么呢?我们需要引入一下这个底范 a sing 可抗抛尘的。用这个来证明一下,他是我们要返回的一个义务,他是一个函数, 他函数里面接受一个工厂函数就是一个回调。那这时候我们可以通过这种引炮他 引炮的函数形式啊,大家要注意,不是这种引炮的 from, 引炮的 from 的话只能在顶层去使用,这是不允 允许参在那个介死逻辑里边,不然会爆错的。但是引炮的函数这种形式是允许的,这种方式他会返回一个 promise, 正好这个工厂还剩,他会接收这个 promise, 然后这个 ctrl 特色,下面这个, 哎,下面 index v, 然后当我们 v 才呢遇到这个音炮,这个音炮的函数形式呢,他会给我们把这段逻辑呢拆分出去,大家现在应该还记得 现在是呃两个包,他会给我们把这个这个组件呢单独再拆出来一个包出来,到时候我们打包的时候,这就会变成三个 ok, 这时候我应该还是没出来,还是没出来的原因是什么呢?需要配合这个微微这个 spas, 一个肚劲需要配合这个去使用,然后它里边提供了两 个插槽。那么昨天讲过了,一个是 dote dfot 来放什么,就是放这个总件的,所以说我们直接给他放进去就行了, 他还有一个插槽,他还有一个插槽是放什么?是一个 fell back, 就是当你这个组件的正在加载的时候呢,你可以为他做点什么,比如说我们可以搞一个 low 的,对, 就是这一步呢,是组建加载的时候呢,我们可以给他来个 logo, 他就会展示这一部分,加载完毕之后呢,他就会把这一部分替换掉,就是替换成我们这个组件了,然后我们可以试一下,我们刷新一下, 我们做一个两毛的延迟 low 定, ok, 那 low 定完了之后呢,他会把我们这些数据呢给他带回来,那只需要配合这个 surpan 去使用的,那这个就是一个义务组件,那就是完全没有问题,因为我们 这延迟了这个两秒钟,你可以延迟五秒钟试试,那他这就会等五秒, ok, 也是没有问题。然后这时候呢,我们再打一下包,你就会发现多了一个这个 gs 跟四 s 出来,他会帮我们把那个去拆分出来的, 把这块逻辑给他拆分出来, ok, 我们稍微等一下, 然后我们再看这个 d 字的下面这个啊 size, ok, 把这个收一下,哎,我们可以看到他又多拆了一个什么 index, 解释出来,其实就是帮我们把这个一步 的逻辑呢给他拆出来,就是他什么时候去调用呢?当我们去使用这个一部组件,或者或者是等浏览器闲暇的时候,他会自己呢去帮我们再去引这个,这样子就节省了这个内存, 然后也节省了这个用户这个等待时间,就不会放到这个主逻辑里面去了啊,这就是一步走这样一个好处。 ok。

那么这期视频呢,我们跟大家介绍 playwright 啊,这个啊,外围应用的自动化框架啊, 那么这个视频的学习呢,大家一定要结合我们的网站上的教程啊,因为后面有很多代码呀啊,大家手工敲的话还是比较麻烦的啊,大家结合我们这个网站, 那么怎么去找到这个我们的这个教程的网址呢?首先我们访问白月黑雨的官网啊,就是三大啊,三 w 白月黑雨点 net, 或者你直接说白月黑雨点 net 啊,然后呢,在下面啊,大家往下找啊,在这个 这部分好有一个 playwrite 啊,点击啊,你就可以进入到啊 playwrite 的这个教程了。那么这个学习呢,大家有一个前提要,首先你要对拍放编程语言要啊,比较熟悉啊,如果你对编程 语言还不熟,那你是没办法学的啊,先学习啊,我们这个啊,你可以先学拍同基础,拍同进阶,先把拍同编程语言学好了啊,那么如果说你有一定的啊,另外一个自动化框架的 基础就更好了,什么呢?就是 selling name 啊,你可以看一下我们这个自动化测试,这边有 selling name 啊,如果你先学过它,那就更好了啊, 当然了,如果你没时间学,那也没关系啊,也可以啊,不用学习,直接啊,进入到我们这个 playwright 的学习也是可以啊,有 snilem 技术更好,那没有也可以啊, 那这个 playwright 呢,是微软开发的 web 应用的啊,自动化框架,那么一看这个描述啊, web 应用的自动化框架,大家脑海里面啊,很多人啊, 就会立刻想起另外一个自动化框架 selenium, 对不对啊?非常有名,那么这个 playwright 和 selenium 的主要有什么区别呢? 那当然,在这个自动化的开发过程中,代码编写上有很多这个区别,这个我们在后面的啊,这个细节的学习中大家会看到,那么我们先从整体上来看,有什么区别啊?啊,或者说第一眼上来看啊, 那么第一个区别呢?就是这个 sleepine 嘛,它在官方文档它也说了,它只提供这个 web 自动化的功能,就说它, 呃,提供给你的是啊,自动化的去操作浏览器啊,或者说这个,呃,基于浏览器的这种技术,比如像 electro 啊这种应用,对不对?那么至于你到底目的是干什么啊?你是说自动化测试呢?你还是说自动化爬取数据呢,对不对?还是说自动化办公,这随你的便啊,这个他并不限定你 啊,那么这个 playwright 呢?啊,他他的重点啊,他这个,他的这个目的就是开发出这个啊工具的啊,这个微软啊,他的目的呢,是面向自动化测试的,他明确就告诉你了,我主要是给你们做自动化测试的。 那其实呢,你做这个 web 自动化测试啊,那你肯定要有,首先你要有自动化的操作 web 的功能,对不对?那就相当于它在 snilim 提供的自动化的功能的基础上,它也包含了另外一部分自动化测试的啊,这种啊,这个框架的功能在里面啊,就是我们可以理解为它包含两部分功能,它还为测试做了特别的准备啊,和特别的支持。 那么听起来呢,就像这个 playwright 啊,它是它的功能比这个 snare name 又多了一个啊,支持测试啊, 那么我们这个教程呢,这个讲解啊,这一套啊,那最主要的呢,不是说我们把测试这块抛出去,那么我们重点就是讲 playwright 的自动化 web 的功能啊,至于测试这一块怎么自动化的支持,那这个啊,你可以啊,结合其他的自动化空间,你可以用啊, playwright 自己带的, 其实他自己带的主要是那个基于 gs 语言的啊,这个其他语言的话,他会基于其他语言的自带的框架,比如说啊, python 的,那就是这个,呃, pur test 啊之类的啊,那么这个我们就不讲了,在这个啊,一系列的这个视频讲解中,我们主要讲他怎么自动化的操作啊, 那么既然我们啊这个视频中啊,重点就讲 playwright 的自动化操作,那 setting them 它就是自动化操作啊,对不对?那这两个具体的这个啊,这个大的这个自动化原理有什么不一样呢?这就是区 区别二讲的啊,那之前呢,我曾经有过啊,这个 cinema 的这个教程啊,大家可以到我的这个网站上,或者到这个 b 站上去找啊,那么学过的人就知道 cinem 自动化的原理啊,大家看一下啊,主要它自动化的这个架构里面,这个最左边这张图啊,它可以分为三部分 啊,那么第一部分,那就是我们的这个自动化的程序,大家看就是这个绿框子啊,包括这里面的啊,这个小红框啊,这个先我们先大体说一下啊,自动化程序就是你写的那个代码运行起来的那个程序, 对不对?然后呢就是浏览器驱动啊,浏览器驱动是什么东西呢?就是专门控制浏览器的,就是我们的自动化程序啊,他不是直接控制浏览器的,他要通过一个浏览器驱动,那么这个浏览器驱动呢?是由各个浏览器厂家自己提供的啊,比如说啊,谷歌的 chrome 啊,微软的 age 啊, r e 啊,对不对? five fox 啊啊?这个,呃,苹果的 suffery 啊,对不对?他们有 这些公司厂家,他们自己开发出来提供给他,所以 sunnym 他还是一个很有影响力的组织,对不对?他的这套东西能够让啊这个得到厂商的认可,去支持他提供这种啊自动化的这种啊,符合这个,呃,他们这个配合的这种浏览器驱动,对不对啊? 然后呢啊?下面再是浏览器,就是说啊,自动化程序,对不对?你自己写的代码。然后呢通过啊,浏览和浏览器驱动之间的啊这个 控制,那它怎么控制的呢?是通过一个叫 web driver 协议啊,这中间这个是个 h t t p 的接口啊,就说你的自动化的命令是通过这个呃 h t p t t t p 的这种接口啊,遵循 web driver 协议,这个 web driver 协议就 是联盟组织定义的啊啊?这个控制浏览器,那么浏览器呢?这个将它命令下发了以后发发给这个浏览器驱动,浏览器驱动啊,再把这个命令经过一系列转化,再发给浏览器,这个浏览器驱驱动啊,居中,就像一个翻译一样的功能,对不对? 话成绩不能直接控制浏览器,就像你和啊,假如说你不会说英语,那你和那个那个英国人讲话的话,中间得有一个翻译,把你们的话翻译成啊,他能听得懂的啊,这种语言和 发给浏览器,那么这个浏览器驱动和浏览器之间的这个协议呢?那就是啊,这个浏览通常是浏览器自己啊,私有的协议 啊,那么典型的就是啊,这个谷歌的啊, chrome deb tools 啊,简称 c d 啊,这个 c d p 啊协议啊,那么像火狐的还有叫 maranet 啊这种啊协议,其实火狐也部分地支持 chrome deep toss 啊,这个是他们的细节了,这个我们就不多说了啊,总之这三大块啊啊 steniem 的框架是这个样子的。 好,那接下来再说这个 playwrite, 它的自动化是怎么做的呢?啊,那首先得看啊,你是用什么这个编程语言,那么其实 playwright 啊,它的第一就是说它的支持的这个最原声的啊,就是说第一个要支持的编程语言是 javascript 啊,这个编程语言,那么这个编程语言呢啊,他是这样的啊,是相当于实力练吗?把这两个合并到一起去了,把这两个上面的啊,就是浏览器驱动和自动化程序合并到一起去,变成这个了, 在 seven 自动化框架里面有三个进程参与了,就三个实体分别在三个进程里面参与了自动化。那么 在这个啊, javascript 啊,编写的这个 playwrite 的啊,这个自动化的程序呢,那它其实就是两个进程了啊,一个是就是你的,假如说是主要这个必须得是 javascript 啊,它运行的其实是用 not just 这个啊, not 啊,这个 javascript 的解,这个相当于解释器了啊,去执行你的啊,这个编写的这个 g s 程序, 那么这个里面呢?哎,也包括了 prewrite 啊,提供的一个库啊,这个库呢,其实就包含了这个浏览器驱动里面,就说相当于原来有浏览器厂商提供的啊,在实验店里面有浏览器厂商提供的这个浏览器 驱动呢,到 playwright 里面,呃,对不起,不要浏览器场上他自己写啊,就相当于他自己开发了这个浏览器驱动,呃,去啊,这个控制浏览器,那浏览器驱动 他只是完成一个驱动功能,对不对?到底你自动化的目的,那得有你自己啊,这个做自动化开发的人,他自己写程序调用他这个库啊,来这个控制浏览器就相当于他只有两个进程啊,但是呢,这个第一个进程里面呢,那他就包含了这个自动化程序和啊,这个 啊,它底层调用的 pro right 提供的库,对的, pro right 的库本来就是用,就是用这个 javasque 的编写的,对不对?那自然化程序自然可以直接的啊,去调用它啊,运行在一个 not g s 进程里面 啊,这是啊,你用 not just 语言开发自动化的话啊,开发这个 play right 的自动化的这个框架啊,这个架构,那就少了一个啊,中间层,中间层相当于合二为一到一个程序里去了,对不对?到一个进程里去运行了,那么如果你是其他语言啊,比如说 python, 那对不起, 按道理说呢,你其实你也可以啊,用就是 play right 库啊,他也可以提供一个啊,比如说用 python 语言直接编写的浏览器驱动,直接控制他,对不对?也可以和他为唯一,但是呢,他没有这么做啊,因为我估计是考虑到工作量比较大,因为这个库并不是那么的简单开发的,所以说呢, 他这个驱动的这个库啊,他仍然是单独的运行的啊,单独运行在一个进程中,那其他语言呢?搞一个客户端库啊,通过这个, 因为客户端库他他就写的代码量就少一点,他只要实现,比如说其他语言的编程接口这一块,像拍同语言,他只要写个拍同语言的客户端库啊,去 playwrite 的啊,去控制这个啊,用 prat 自己开发的 gs 语言开发的这个啊,浏览器驱动,注意哦,它和 sleep 的区别,这个是由浏览器厂商提供的,这个还是 prat 组织? 就是微软啊,他自己啊开发的对不对?然后啊,再控制他,其实他大体的架构啊,如果是其他语言,实际上跟 snileme 是很像的,只是这个浏览器驱动由官方提供变成了啊 playwry 的自己提供,对不对?然后呢,还是用其他语言调用 playwry 的客户端库去控制它,对不对?这个就跟 selemium 其实蛮像的了 啊啊,只是中间这个库呢?啊,换掉了啊,不是用这个官方提供的驱动。 那么这个控制原理呢,那就是和 snare name 就很像了,因为我们接下来主要讲的就是用拍同语言啊去开发的,那么那也是你自己写程序啦,然后 调调用这个 play right 的客户端库,对不对?呃,你的程序发指令通过这个客户端库啊,呃,发送通,这也是通过这个网络协议啊,通过这个发送给这个浏览器驱动也是通过网络哦? 呃,浏览器驱动是一个独立的进程啊?是,也是一个 note j s 运行的一个独立的进程啊。发送给他,让他去控制浏览器,对不对?这个大体的自动化原理我们讲了,就跟十点零其实很像,这个三块啊。