00:00
现在已经知道在代码里边怎么样去用这个process方式,然后里边它有什么样的特性啊,我们发现这里边可以获取到当前的时间戳water mark,呃,可以去注册定时器啊,还可以去做这个测殊输流的一个输出,所以能做的事情非常多,当然它还可以做这个就一般的rich function里边做的事情,对吧?生命周期,然后定义状态,这些事情通通都能做。那接下来我们就还是理论指导实际来做一个具体的需求,那现在这个需求是什么呢?呃,前面我们做那个状态编程的时候,给大家提了一个需求,是做一个,呃,就是前后两次输,呃,这个输入的数据判断它的温度差值超过一定数据,现在呢,给大家另外一个需求,我判断的不是前后两次去做对比,而是怎么样呢?我判断的是,假如我现在在十秒钟之内,温度是连续上升的一个状态的话,我就输出一个爆。
01:00
警,大家想想这个需求该怎么去实现,这个感觉就很奇怪,对吧?它跟时间有关了,就是如果十秒之内连续上升的话,我就是输出一个报警,有同学一提这个时间可能就想到,哦,那开个窗口啊,我们去用一个时间窗口搞定这件事儿啊,这是一个很好的想法,那首先我就想到那怎么做呢?那肯定就是还是我先把这个先住掉了啊,这是之前的这个做法,接下来我们可能会想到,哎,我去定义一个这个warning stream,做做报警的这样的一个stream,那就是基于这个data stream先去做一个K,还是基于这个ID先做一个分组,然后呢,哎,可能去创建一个time window,这个time window你不是这个十秒钟之内连续上升吗?那我就给一个十秒嘛,对吧,time.seconds前面要把这个对应的包引入,这个是window in time.time然后seconds。给一个十秒,哎,这不就完事了吗?对吧?然后接下来,呃,可能就是后边里边的这个我们的那个window,它的操作那个窗口函数稍微会麻烦一点,我相当于得有一个,呃,如果是连续上升的话啊,大家可能想到我得呃有一个这个所有的数据都收集起来,然后判断它是不是连续上升啊,或者说我就一个一个去判断是不是总比前面那个数大,对吧?呃,我就总是判断这个,如果要是不是比那个前一个数大的话,我当前窗口就不输出内容了啊,这个可能定义的这个逻辑会稍微的复杂一点,但是感觉好像可以实现,但这种实现方式有没有什么问题呢?
02:41
大家仔细一想的话,其实会发现啊,窗口这样我定义了一个滚动窗口,对吧,你这么去定义的话,那相当于是什么呢?就是我在这里边,这是一个十秒钟的窗口,然后假如说我的数据诶,刚好就是在这个这个时间范围内,它就是连续上升的,比方说我用这个上向上的这个箭头表示比之前的一个是上升的,对吧?如果说我都是这样的一个状态的话,哎,那当然我可以判断出来,当前这十秒钟之内温度连续上升,我输出一个报警信息,但是其实大家会想到啊。
03:18
往往我的这个情况有可能是什么呢?呃,这是下一个窗口对吧?有可能是什么呢?我在中间来了一个数据,有可能这个温度下降了对吧?呃,这里边我我从这边往这边看啊,这是前面的数据,这是后面的数据,然后后边来的呢,又连续上升了,那大家看这个窗口内是不是它不是连续十秒连续上升啊,诶那他就不警了,当然不报警了,对吧?那后边呢,这个窗口有可能诶温度又上升对吧?温度又上升,然后这个温度一直是上升的一个状态。上升诶,但是到后边的时候,某一个值温度又下降了,对吧,温度又下降了,那是不是下边的这个窗,后边这个窗口也不报警啊。
04:03
但是大家仔细看一下中间的这个过程。是不是很有可能已经超过十秒钟了呀,对吧,中间这有可能是很长一段时间,它都是温度连续上升的情况,按照我们的定义,你这就应该报警啊,哎,你这种情况根本就没有报警,那这怎么办呢?哎,有同学可能想到了,那这个滚动窗口不行对吧,滚动窗口不行,那我我来一个这个滑动窗口吧,滑动窗口前面这十秒后边,哎我在我在动对吧,隔一小段时间我就滑动一次,这样总能把它这个呃中间的这这这种情况都都包括在内了吧,对吧,我总能有一有某一个窗口里边,它这个数据都是连续上升的这种情况吧。但是大家注意啊,你滑动窗口是不是也得有一个滑动步长啊,啊,除非你说你这个滑动步长非常非常小,小到什么程度,小,小到一毫秒,我们当前处理的这个最细微最小的那个单位对吧?小到那种程度,那就相当于你每秒每个毫秒都去判断了嘛,那如果说你这里边还是要滑动一段距离的话,隔一段时间才去统计一下这个窗口的话,那就会出现什么情况呢?哎,那就是我们说的,你看在前面这个窗口里边,哎,当前这个窗口里边连续上升,我就不画这个数据了啊。
05:19
当前这个窗口里边连续上升,连续上升,这都是连续上升的,对吧。我我就大概这么画了啊,但是呢,诶到最后这里面下降了对吧。呃,这这这个我先不这么画啊,就是这个窗口是前面有一个下降,就第一个窗口啊,第一个窗口是前面有一个下降,后边这里面没有下降,都是上升的,我先把这个给大家重新一下啊,后边都是一直都是在上升。然后呢,我就是前面这里边下降了,那第一个窗口是不是不是连续上升,对吧?啊,就是我这里边肯定是前面上升中间下降,然后后后边又上升了,然后第二个窗口呢,诶大家看到第二个窗口,那可能我到后边这里边来的时候,呃,就是又会有一个位置,有可能会出现这样的下降的情况,对吧,那中间全是上升,那你说是不是他俩中间的这种情况下,这种情况下。
06:20
是不是还是有可能有十秒钟的时间是连续上升,但是我们没有没有把它给提取出来啊,所以在这种情况下,你会发现窗口的这种统计模式啊,你只要不是连续每个毫秒都去统计,那它总是有涵盖不了的情况,对吧,总有这个缝里面插进来的这个刚好十秒钟你检测不到。啊,那有同学说,诶,那这种情况是不是我要去用一个session window之类的东西呢?会画窗口呢,会话窗口也不是一回事,大家想想会画窗口是什么呀?哎,是你当前数据啊,哎,他们之间的之间的这个间隔比较小,对吧?这是一个窗口,如果之间的间隔超过了一段距离的话,哎,那就开始下一个窗口,那你这样的话,这相当于是什么,我得看他们俩之间这个这个这个时间隔了多久,对吧?然后统计一个一个窗口里面的数据啊,那你你如果说,呃,就是说这里边你的这个时间啊,你GAP如果设置成十秒的话,那你只能保证是什么呢?就是我前面统计到的这个窗口里边,哦,这是温度,诶我我看它到底是这个连续上升还是有下降,诶我去统计一下,然后中间如果隔了十秒的话,那接下来我做这个操作的时候,呃,下一个窗口我可以去判断一下到底是连续上升还是下降。
07:42
但大家想大部分情场景应该是什么呢?应该是数据非常的密,对吧,数据非常的密,你根本就没有十秒的这个间隔,然后在这这中间呢,有上升有下降,有可能有些时候就连续十秒,它是一个上升的一个状态,你这个怎么能能直接把它截出来呢?对吧,你没有办法用那个GAP间间隔,一个这个绘画间隔的这种方式把它区分开啊,你你这个东西只能判断我们这个离得比较远的这种情况啊,所以这些都搞不定,那都搞不定怎么办,怎么办呢?这种时间怎么去处理呢?
08:20
哎,这就是我们之前说的定时弃码,我可以怎么样呢?来了一个数据之后,哎,当然我可以有一个判断条件,比方说我要求就是这个数据首先是在之前的基础上上升了,然后我就开始啊,我就觉得这是接下来可以连续上升了,对吧?呃,连续上升的前提是要先上升嘛,那接下来我就注册一个定时器,就从当前我判断某一个这个数上升这一点开始。没有窗口对吧,我从这一点开始定义一个定时器,然后十秒之后出发,然后在这个范围内,这个时间内所有的数据我把它收集齐,然后判断是否到时候要输出一个报警,对吧?啊,这样的话其实就处理就比较简单了,所以当前的这个你也可以认为是开了一个窗口,好像是开了一个窗口,但这个窗口呢,时间并不对齐对吧?时间并不不确定,我是按照这个数据某种条件下才开开启这个等待的窗口,所以这里边其实是定义了一个定时器,定义了一个我们这个闹钟而已。
09:26
啊,所以接下来我们就得用那什么样的呃,API可以用到这个闹钟,这个定时器呢,那就只有process function了,对吧?啊,所以接下来我们就是定义这样的一个process方式,那我们定义的这个操作我可以管它叫,呃,当然就是直接叫process了啊K之后我们要传一个实现一个kid的process方式,这个我们就叫做就是连续上升报警对吧?温度连续上升我们叫温度increase吧,Increase warning,呃,然后同样这里边我也可以传一个参数,就是表示间隔多长时间对吧?呃,就是我判断是多长时间内连续上升我就报警,比方说我现在是十秒钟,我传一个十,或者我传这个毫秒数吧,对吧,我直接传一个这个1万,这就是我们的那个时间戳毫秒数嘛,接下来我就来实现这个东西啊,我们之前的这个是一个测试啊,Key的process process function。
10:26
功能测试,然后现在我们是要实现这个具体应用的时候啊,实现自定义的key的process方式。好,那接下来我们这个本身类的定义还是大同小异啊,把它先写好,呃,Tap in increase warning,然后当前的这一个我们管它叫做,呃,这这个其实就是我们现在用到的这个一个时间间隔了,对吧?呃,Interval啊,然后接下来它需要去继承呃,实现我们这样一个抽象,这是一个抽象类啊,Key的process方式,然后KIO啊,三个数据类型对吧?啊,那首先K当前是string ID嘛,然后这个输入数据,Sen reading亮例类类型输出的数据,哎,那我们还是string直接输出一个报警信息完了对吧?啊,因为你这个是连续温度上升嘛,这个不像我们之前那个三元组两个温度输出啊,所以先把它直接写出来,然后里边必须要实现的是一个process element的方法,对吧,必须重写的啊,然后接下来还有就是我们想到在这个过程当中,是不是得定义一些状态呀,啊,所以接下来我们。
11:45
先把这个状态定义出来,呃,它本身是reach方吗?可以定义状态对吧,你要去判断它温度连续上升,那怎么样去定义状态呢?哎,有同学可能说,哎,那我这个就定义一个,呃,就是上,就是定义一个list state对吧?我定义一个列表状态,然后呢,把所有的每来一条数据都塞进去,每来一条数据都塞去,然后到最后的时候呢,我把这个数据全拿出来,挨个做一个比较,看它是不是是不是这个连续上升,哎,这是一种实验思路啊,但但这种实验思路稍微有点麻烦,其实大家想到我可以怎么去做对比呢?我不用把所有数都存下来,这就有点像批处理了,对吧,我可以怎么样呢?我可以来一个数就比较一次,为什么呢?因为你要连续上升嘛,那连续上升,我只要中间有一次比上一次的那个温度值低了,这不就相当于中断了吗?这个不是连续上升了,然后我就直接把它打断,然后我就重新开始,重新开始等这个十秒钟对吧?啊,就是相当于呃,这个。
12:45
含义就是说我一开始如果发现一个数据比之前上升了,然后接下来就怎么办呢?定义一个定时器对吧?定义定时器开始等,如果后面一直是上升,一直是上升的话,我这个定时器就一直放在这儿,我就一直等到十秒钟结束的时候,如果它还是一直上升的话,那我就出发一个报警,输出一个报警信息,如果在这个过程当中怎么样呢?来了一个下降,来了一个下降出去那怎么办呢?啊,其实我都不用去做任何操作,我怎么样直接把这个定时器删了不就完了吗?大家想想对吧,当前我这个定时器就没用了,当前已经十秒统计的这十秒周期内,它已经有下降了,那接下来就相当于这个这个定时机作废了嘛,肯定不需要报警了嘛,直接删掉就完事儿了,然后接下来呢,如果又下面来一个数这个上升,那怎么办?再基于它再去注册一个定时器对吧,等着这个闹钟十秒钟之后再响啊,所以接下来又是这个过程对吧,如果是上升的话,上升的话就一直等。
13:45
下降的话就把它删了啊,所以我们现在思路就变成这样了,那这个状态其实非常简单,我只要判断当前的数比上一个温度是大了还是小了就完了,对吧?啊,所以这个状态跟上一次我们那个呃,保存上一上一次的温度值啊去呃,判断它是否跳变,其实有点类似,我也只保存上一个温度值就完事了啊,所以我们定义状态啊,定义状态保存上一个温度值进行比较,对吧,判断到底是不是要做这件事情,然后另外大家还想到一个我还得做什么事呢,因为还涉及到一个要删定时器。
14:28
这个删定时器就稍微有点麻烦,因为大家想到前面我们那个删定时器必须得传它那个时间戳对吧,你注册定时器的时候简单,我是用当前数据,呃,它的那个时间,然后再加上十秒注册就完事了,但是你要删的时候它还是当前数据吗?那就不是了,之前我们看到你要删的时候,那是因为它有一个数据下降了对吧,就有一个那个温度值下了,那之前注册的时候的那个时间点我根本不知道了,已经,那怎么办呢?啊,把当时注册的时候那个时间点也保存成状态不就完了吗?哎,所以接下来我们这个保存的状态是要保存上一个温度值进行比较,还有保存,呃,就是注册定时器的时间戳用于删除对吧?啊,所以接下来我们要定义这样的两个状态啊,那首先我用lazy的方法去做一个定义啊,啊,那首先是还是last temp state啊,这个就算了,我直接把下面这个copy过来完事了,对吧,我们之前那个state,呃,Test里边,这里边不是定义了,这个我是一是一个直接它。
15:44
好,放到这儿好啊,里边的定义都完全一样对吧?然后另外呢,哎,我这个就简单写了啊,不想一个一个写了,直接先copy过来,然后接下来呢,后边还需要有一个就是当前定时器时间戳的那个啊,一个一个状态对吧?所以这里边我可以定义一个timer ts state它的时间戳,那这里边时间戳我们知道是一个长整型,所以这个数据类型改过来,Y6STATE也是一个值值状态,里边是一个长整型,然后里边呢,类型也得改,注意这个名字必须得改,对吧?啊,千万不要不要叫一样的名字啊,这是timer ts里边这个类型改了长整性,这样一改的话,这就没什么毛病了,然后接下来就是process element process element,我们知道是每一条数据来了之后都会调到这里的方法啊,然后这里边我们还有一个上下文对吧,可以调那个时间服务注册定时器啊,那现在我们就来考虑了,首先。
16:45
应该干什么,先把那个状态先拿出来,对吧,先把那个状态上一次的温度值我们要拿出来嘛,定时器实验我们也拿出来,先取出状态。啊,因为本身这个状态不好用啊,我们就是先得把它定义成一个本地变量,这样的话接下来使用起来就方便多了啊,Last time state value拿到,然后另外我们还有个S,把这个当前里面拿到,先取出状态,然后接下来我们就要判断判断当前温度值和,啊,就是其实就是当前温度值和。
17:34
上次温度进行比较,哎,那就是一个衣服喽啊,那我们这里边当前的温度是value.temperature然后如果它大于上一次的这个last temp的话啊,然后这里边还可能还需要有一个有一个要求是什么呢?就是我需要做一个初值的判断,对吧?类似于前面那个问题,假如说你一上来的话,这里面这个都是零嘛,你第一个上来之后,你发现诶又是零,直接直接做这个输出了,那怎么办呢?这里边我们有一个小小的这个技巧,因为上一次跟大家说过,你可以单独再定义一个标志位作为状态,对吧?或者说给一个永远取不到的一个初值,然后去判断那个初值,我们这边可以借用什么呢?可以借用这个time啊,借用这个时间戳啊,因为大家想我这里边时间戳初始值应该定义的是什么呢?也没有初值,它是个长整形,当然就是零了,零表示的时间是什么?哎,那是1970年月一。
18:34
到零点那个时间点对吧?哎,那正常来讲,我们正常注册的定时器肯定不可能是零,对不对,所以我可以判断,如果这个timer state它是零的话,我就认为这是第一次对吧?这种情况下我就不要去输出,呃,就就相当于不要去注册定时器了啊,所以这种情况下就是就是这样的一个状态,而且我们会想到,如果后边我们要是删了定时器的话,接下来要再去注册定时器的时候,是不是也是我们删定时器的时候,同时就把这个状态也清空清成零,那后面是不是判断如果这个状态又是零的话,我就又可以注册新的定时器了,对吧?你如果要有定时器的话,那就不要注册新的,你就还是按之前那个十秒等着就完了啊,所以接下来我们有一个小窍门,就是判断当前的定时器的这个状态,就是台门TS,如果说它等于零的话,这个时候我们才去注册一个定时器,对吧。
19:34
把这个写一条注释啊,就是如果温度上升且且没有定时器,那么注册当前。数据时间戳时秒之后的定时器对吧?啊就是这么来定义,那所以接下来我定义一个我要注册的这个时间戳啊,这TS啊,那用什么呢?呃,就是那那现在其实大家知道就是我不用这个当前时间戳了,因为我现在没有定义那个事件时间对吧,我干脆就用处理时间好了,那其实就是用当前时间,是当前时间十秒之后的定时器对吧?那我这里边就是get,就应该是,呃,就是我当天如果注册这个时间的话,应该用timer service里边去get时间,呃,不是get时间啊,用current时间对吧?当前时间我就直接用这个processing time处理时间就完事了,然后呢,十秒之后,哎,这个十秒其实我是参数传进来的interval对吧,当前这个类一开始就把这个时传进来了嘛,而且我传的是毫秒,所以我就不用乘1000了,直接加上就完事了,注册这样一个定时器,那还得调用。
20:57
Timer service register even,呃,不是processing time,对吧?Processing time timer把它定义出来,然后另外不要忘记还要做一个状态的保存,海rate是不是要做一个update啊,对吧?把当前的这个时间戳保存到我们的这个状态里面来。
21:18
好,这是这个,如果出现了这种情况啊,那另外还有一种情况是什么呢?就是如果这是温度上升,而且它没有定时器,那有同学说如果温度上升。已经有也有,也已经有了定时器,那怎么办呢?那说明是什么呀?说明是就是我现在的这个状态是前面来了一个温,呃,温度上升,已经注册了一个定时器,对吧?然后接下来是不是温度连续上升啊,相当于是那连续上升我干什么事呢?啥都不用干嘛,你就等着这个定时器十秒之后,到时间你输出报警不就完了吗?对吧?现在如果是连续上升啥都不用干,那但是有一种情况你要做判断什么呢?就是现在温度下降了,下降的话是不是我就得删定时器啊啊所以这种分支我们要做一个考虑,Else else这里边还有情况,那就是如果value.temperature如果小于last time的话,哎,当前啊。
22:22
我们如果温度下降。那么删除定时气对吧?是做这样的一个考察,呃,这里面应该没什么问题吧?呃,那接下来我们是要删除定时器,怎么去删呢?还是timer service去做一个delete,哎,前面注册的是什么,我们现在就要删什么,对吧?Processing time timer,那这里边我们删的那个时间戳是哪个呢?哎,当然就是有些同学说,哎,TS嘛,不是TS对吧,TS是你要注册的时候定义出来的那个东西,它作用欲只有只有在if里边,我们现在时间戳是什么状态里边拿出来的时间戳,所以是timer ts把它放在这儿,然后另外还需要去,呃,大家注意还要去做一个清空状态,对吧?啊,现在这个报错应该是我们这个。
23:20
呃,看看一眼啊,是不是这个括号稍微有点问题,当前这个括号。这是process element里边的,这是这个else里边的,应该是应该是对的对吧,应该是没有什么问题啊,那接下来我们还得把这个状态做一个啊更新啊,那你可以把这个就是TS直接update成零,对吧?那或者可以怎么样呢?还有另外一个方法,非常简单的清空状态的方法,直接把它做一个clear就可以实现这样的一个过程了。啊,所以这个定义其实还是非常简单的啊啊哦,这这里面是我这个语法写错了对吧?Else if嘛,不是不是直接else是吧,Else if,如果要是出现小于的这种情况的话,我们要删除定时器,而且把状态清空,那下一次又来的时候,是不是就判断如果继续温度上升的话,我就可以继续再去注册定时器了,对吧,这里就又是零了啊,所以大家要把这个逻辑要理顺啊啊那看这个代码就写完了对不对,不是有同学可能想到了,那你定时器触发的时候报警怎么报,还还没没说呢,对吧?那报警是在哪里报呢?定时器触发的时候才报,这个触发的时候那是要实现一个on timer方法,对吧?这里边是真正的触发时候要调的操作,那我们这里边非常简单,因为只要它触发,大家想如果你没有被删掉,没有中间被删掉清空的话,那是不是这里边触发的时候,肯定这十秒之内温度是连续上升的呀。
24:57
啊啊,所以这里边我就干脆直接输出就完事了,out.collect直接输出对吧?啊那比方说这里边我输出一个信息传感器啊传感器谁呢?呃,我这里边加一个啊,用当前的这个ctx里边的K,大家知道这里的K就是当前的3ID对吧?啊传感器这个啊它啊,我们说它的温度连续连续多少秒,我们把那个传进来对吧?呃,除以1000,这个得我们传的是本身是一个好秒数,然后接下来哎这么多秒。
25:41
连续上升对吧。这就是我们最后要输出的一个字符串类型,我们要的不是这个数字符串类型吗?你在on timer里边,大家看它也有这个collector,也可以做输出啊,所以说这里边能做的事情还是比较多的啊啊,那注意最后不要忘记你已经做完这个输出操作了,那这个定时器相当于不用删了对吧?呃,闹钟已经响了嘛,那当然就不用再做删除了,但是我们需要把当前的这个timer的TS的state做一个清空,对吧?把它做一个清理啊,那有同学可能问,那你那个last time需要做清空吗?这个就看你逻辑定义了,我们这里面不清空就是总保持着上一次的那个温度值,你要清空的话,下一次来了之后,相于他又是走我们这个流程,就是不先判断对吧?那就相当于是先去把这个,呃,第一次的那个温度值先先给它这个负值负进来啊,先做一个这个操作了啊,所以这个整体来讲还是差不多的啊呃,这把这个on time。
26:47
完之后,整体的逻辑才真正的写完了。这就是利用process function实现这个代码的一个过程,好,那我们还是把这个执行起来,来快速的测试一下,看看这个效果到底怎么样,我们现在是呃,用这个流数据输入,然后是当前是这个处理时间,Process把它运行起来,接下来我们在这儿去输入数据看一看效果,好现在这个已经提起来了啊,那我们接下来还是第一条数据,35.8先输入。
27:19
然后现在诶这里面没有任何的这个输出肯定的对吧,一一开始上来之后,第一次他没有任何的判断嘛,然后36这条数据,因为处理时间嘛,我们这个时间说没有任何的影响,然后我们再来一个38,当前这是相当于是在连续上升对吧,大家看到这是在连续上升的一个状态,39啊,然后我们继续看,继续给40。诶,这里边大家看到好像没有任何的输出对吧,好像感觉已经已经等了十秒钟了,这是为什么呢?诶,这肯定是代码里边有问题啊,我们看一下这里面的代码你会发现,诶这里面只做了这个操作,我们后边是不是执行是执行起来了,但是忘记了print打印输出对吧?那这里当然没有输出了,好,我们先停一下啊,把这个还是代码加进来,Warning stream做一个打印输出。
28:16
启动。好,那接下来我们重新来测试一遍啊,还是35.8,先给一个对吧,然后我们这个36啊,后面继续往上升38啊,再来一个40。40.5啊,诶大家看这里边基本上就是我们第一个数据输入之后等了十秒钟,这里边就输出了一个连续十秒,呃十秒内连续上升对吧?哎,你在这个过程当中,你可以等很久,你会你会发现它并不是那个我们窗口式的那种操作,呃,它其实就是按照你当前输入的第一个数据来判断的,那你如果在这个上升的过程当中啊,呃,如果说比方说我们后面还是啊36 38,然后如如果中间有一次下降的话,35.8,那你诶这个你看我这个书慢了对吧?所以这里面它已经已经是提前把这个输出出来了,我们再稍微输的快一点啊,重新来一遍,35.8 36 38 35.8,然后如果我们在等这个过程的话,你会发现到十秒的时候,诶,这里边大家看到还是在这个连续上升,这是为什么呢。
29:32
这肯定就又是代码里边有问题对吧?呃,就是我们预期应该是如果你中间做了这个下降的判断,如果能把这个当前数据能清掉的话,应该是就不会出现这个呃连续报警的这个效果了,对吧?当前的这个呃定时器应该是直接就被清掉了,那当前为什么他还会有这样的一个呃。对应的这个输出呢,说明我们前面有一些操作是没有做到的,好大家看到逻辑里边,其实整体逻辑是顺的,是这个判断都是没有问题的,但是问题就在于什么呢?我们这里边更新状态的时候,只更新了当前的,呃,就是如果注册了定时器,或者说删除定时器的话,我把这个定时器时间时间戳这个状态更新了,那大家想我这里面的这个上一个温度值更新了吗?
30:28
没有更新对吧,那么没有更新的话,是不是这个温度值永远都是初始值,也就是说永远都是零啊,也就是说这里边我们的这个判断,大于的这个判断,它是不是永远都都是成立的呀,对吧?这里面就相当于永远不会现,而且后面我们的给的值都没有负的嘛,所以永远不会出现小于的这种情况,那当然就不会删除定时器了,所以之前我们看到输出的时候,就永远都会有定时器的一个出发,对吧,永远都在报警,所以这里边的核心问题在于你来了数据之后,是不是最后就是处最后处理完了也可以,或者说因为我们已经把这个拿出来了嘛,对吧,相当于已经有了保存了,或者我前面趁机的是不是就直接就把这个状态更新掉啊,对吧,哎,更新更新。
31:21
温度值就是上次的这个温度值对吧,把当前的温度值当成这个上次的温度值,就相当于是这样的一个更新,我要更新的是这个状态对吧?我要不是改这个last time,这个已经拿出来了,现在我是要把它改成当前value的temperature啊,这样的话,接下来我们再来测试一下,运行一下看看。再来我们这里已经运行起来,还是重新来测一遍好,第一个35.8对吧,首先我们测正常的啊,36,三十八四十啊,随便42啊,我们先等一等看看十秒钟的时候,诶,正常数出了一种情况对吧?然后接下来我们看35.8,三十六三十八这个得输的稍微快一点啊,再来一个35.8,这中间有了一次下降,然后可以我们多等一会儿,看他是不是就不会再输出报警了。
32:21
诶,大家看现在好像等的时间已经够长了是吧,他不会输出报警了,这就是因为我们现在是真正的按照他上一次的温度值来做的对比,而不是跟初始值零做对比,然后现在对比发现它下降了,那当然就把那个定时器就删掉了,对吧?只要这里删掉定时器后边就不会再去触发输出这个报警信息了啊,这就是这部分代码来下来之后要好好练一练啊。
我来说两句