Javascript的回调,不等同于MCU的中断

曾有一位做单片机开发的朋友问我回调是怎么回事,我解释就跟单片机的中断函数类似,比如你的定时器的溢出值设置为200毫秒,那么单片机内部电路每200毫秒,就会把PC设置成你的定时器中断向量入口,达到调用中断程序的目的。在浏览器上,JS引擎负责做这个事,回调函数就相当于ISR。

后来一想,这种说法有问题。只怪我当时对Javascript的特性不是很了解。表面上看它很恰当,但是却让人忽略了一些重要的问题。MCU的中断,是那种会直接打断程序流程的东西,而Javascript的回调,会很绅士地一直等下去。

MCU是怎样的?

还是拿「定时器中断」来说,当定时器的计数器溢出或达到阈值,就会改变内部一个标志位。正在运行的指令执行完后,这个中断标志就会被处理,不同的MCU会有不同的处理方式。

大致原则是:

  • 除非正在处理更高优先级的中断,否则立即响应定时器中断,调用中断处理子程序。
  • 当正处在其他不可打断的中断(可能是优先级高,也可能是CPU本来就不支持打断),那么就等着,那个一完,这个就立即响应。

也就是说,基本上MCU会立即响应!

单片机工程师在这一块会非常小心,举个例子,当MCU字长小于数据的字长,比如在8位机上使用int,如果这个值碰巧也会被ISR修改,就需要在处理int前,先关掉全局中断,处理完了重新打开。因为你不知道什么时候中断会产生并打断你。

出于类似的原因,软件开发人员编写多线程程序时,经常需要「加锁」。

Javascript是怎样的?

我们拿JS的setTimeOut来做个实验。(正好和定时器中断做个对比)

setTimeout(() => console.log("cool"), 1000)

这个会在1秒钟后,打印出一个“cool”。一切在预期中,与「MCU中断」行为类似。

举其他的例子之前,我们先定义一个函数,通过死循环来达到延时的效果。

function sleepSync(ms) {
  var mark = new Date().getTime()
  while (new Date().getTime() - mark < 4000)
}

再看另外一个例子

setTimeout(() => console.log("cool"), 1000)
sleepSync(4000)

出问题了,过了4秒之后才打印出“cool”。setTimeout并不能打断那个while死循环。

用其他的Javascript函数做个实验

// let's try to read a non-existing file
fs.readFile("/tmp/blah", (e, _) => console.log(e.message))
sleepSync(4000)

同样是过了4秒,才打印出

ENOENT: no such file or directory, open '/tmp/blah'

所以JS的「回调」和「MCU的中断」,是不能等同的,它们有一些相似点,但是在关键的地方不太一样,所以以后还是不要打这个比方吧。

至于Javascript为什么是这个样子,这跟Javascript的Event Looptask queue有关了,但那是另外一个主题(如果感兴趣,请看另一篇博客),这篇文章只是纠正一下过去自以为很棒的比喻。

原文:http://madmuggle.me/articles/JSCallbackIsNotMCUInterrupt.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容