在底层C语言中,有一个非常重要而特别的概念,叫做“中断”。用比喻来说,我正在写着博客,突然我妈打个电话过来,我就离开了键盘去接电话了,然后写博客就中断了,我聊完电话回来再继续写。乍一听似乎并没有什么大不了的是吧,似乎没什么好说的。那具体在程序中怎么表现的呢?一台电视正在放着节目,我用遥控器一按,它就不得不转过来处理红外遥控的信号,要不然微有差迟的话,遥控信号就过去了,也就遥控失灵了。只有处理了这个遥控,然后它才能再转回去处理它的视频和声音。这就是中断。
在JS中,也有一个非常重要而特别的概念,叫做“异步回调”。同样用比喻来说,我给经理发了封邮件,不可能一直晾在这里干等他回邮件吧,于是我先做其它的事情,等看到邮件通知了,我再回来处理这份邮件,这就是回调。在网页程序中,最常见的回调莫过于AJAX请求了,发出了一个请求,不能让浏览器一直卡死在那里一动也不能动就等着服务器发数据回来吧,这种一收一发一般也要一两秒钟,如果是这种一卡一卡地估计就没人想用了,所以现在浏览器中绝大多数都是使用回调。
“中断”和“异步回调”有一个很相似的地方,那就是都是放下正在做的事情,先转去做另外的事情,然后再回来处理。不同的是,“中断”是被外界打断现在做的事,紧急去处理了再回来继续做,而这个紧急处理一般来说要尽量简短、耗时非常少,比如前面的电视机总不能按一下遥控就黑屏静音了半秒钟吧,所以中断函数会要求写得尽量简短。而“异步回调”则是,我知道我要等一会才能得到答复,所以我先做着其它事情的一种主动式的行为转移,等得到答案了再回来处理原来的事情。据说NodeJS可接受的并发量很高,大概就是这个原因吧,数据库反应不过来就让它慢慢来,这些人都在我这里排着队,排完一队折回来又一队。而其它后端一般是同步的,数据库不够用的时候,就像队伍排到了门口但又不能折回来,后面来的就只能到大街上等吧。
说了这么一堆,那代码是个什么样子呢?下面这个就是一个典型的C51定时器中断程序,可以看到它有 interrupt 和 3 作为标识它是一个中断程序,序号为3。但其实还有非常重要的一点是,程序任何地方都不能调用这个函数,因为“中断”是一个由外部因素(这里是定时器计数满了)引发的一个行为,硬件机制会自动触发这个函数执行,如果又允许其它程序调用那将会导致混乱。
//Timer1中断服务程序 void time1Isr() interrupt 3{ //重装数值 TH1 = (65536-92)/256; //定时100us TL1 = (65536-92)%256; //翻转IO口电平 发声 if (onBeep == 1){ beepC++; if (beepC >= 5){ beepC = 0; BuzzerIO =! BuzzerIO; //这里是电平翻转哦,频率快的话就能听到声音了 } } }
JS异步回调就常见了,就是把函数放在另一个函数的参数里。这,好像是类似于“函数指针”的东西?那是不是其它语言也可以在需要的时候使用这种“异步回调”的函数?
$.post("someURL", {key:"val", key2:"val2"}, function( result ){ console.log( result ); });