一个栗子引发的思考
前情提要:小 Foo 和小 Bar 是某互联网公司的同事。有一天,小 Foo 交给小 Bar 一个任务……
轮询(Polling)
小 Foo 说明任务之后并没有回到自己的工位,而是站在小 Bar 后边执行了以下方法:
1 | while (!Bar.getRes()) { |
这就叫轮询
阻塞 (Blocking)
小 Foo 说明任务之后并没有回到自己的工位,而是站在小 Bar 后边执行了以下方法:
1 | while (!Bar.getRes()) { |
此时小 Foo 是阻塞
的,因为 Foo 在等 Bar 的结果什么也没做。
非阻塞 (non-Blocking)
小 Foo 说明任务之后并没有回到自己的工位,而是站在小 Bar 后边执行了以下方法:
1 | while (!Bar.getRes()) { |
此时小 Foo 是非阻塞
的,因为 Foo 在等 Bar 的时候还玩了炉石传说。
同步 (Synchronous)
小 Foo 说明任务之后,小 Bar 说:“你先回去吧,做完我告诉你”,小 Foo 说:“不行,我就要在这看着你做!你做完了我才能玩炉石传说!”并执行了以下方法:
1 | while (!Bar.getRes()) { |
此时的工作是同步
的,因为只有 Foo Bar 做完了这个工作 Foo 才能玩炉石传说。
异步 (Asynchronous)
小 Foo 说明任务之后,小 Bar 说:“你先回去吧,做完我告诉你”,小 Foo 说:“溜了溜了”,并执行了以下方法:
1 | Bar.addEventListener("我做完了", () => { |
此时的工作是异步
的,因为这个工作还没做完,Foo 已经开始了下一个活动(玩炉石传说)。
并发 (Concurrent)
小 Foo 说明任务 A 之后,发现自己还需要让小 Bar 做任务 B。
小 Bar 先做了任务 A,或者先做了任务 B,或者一会做任务 A 一会做任务 B,或者任务 A 任务 B 同时做,总之,在下班之前交付给了小 Foo。
此时的工作 AB 是宏观并发
的,因为在同一时间间隔(下班之前)里,AB 被执行。
并行 (Parallel)
小 Foo 说明任务 A 之后,发现自己还需要让小 Bar 做任务 B。
小 Bar 觉得自己非常厉害,所以他左手做任务 A,右手做任务 B。
此时的工作 AB 在某些时间点是并行
,因为在一些时间点上,AB 是同时被执行的。
串行 (Serial)
小 Foo 说明任务 A 之后,发现自己还需要让小 Bar 做任务 B。
小 Bar 觉得自己非常菜,所以精心规划好了工作时间,先做 A,然后做 B,最后检查一遍 A。
此时的工作 AB 是微观串行
的,因为在同一时间点,只有一个工作被执行。
函数节流 (throttle)
小 Foo 说明任务之后并没有回到自己的工位,而是站在小 Bar 后边执行了以下方法:
1 | let cui = () => console.log("做完了吗?做完了吗??") |
小 Bar 觉得小 Foo 这样做很不利于工作,于是给小 Foo 加了一层函数,这样小 Foo 无论怎么想催,一分钟最多催一次。
1 | var throttle = function(fn, interval) { |
这个方法叫做函数节流
函数防抖 (debounce)
小 Foo 说明任务之后并没有回到自己的工位,他觉得小 Bar 写的太慢了,于是执行了以下方法:
1 | Bar.addEventListener("input", () => console.log("做完了吗?做完了吗??")) |
这样小 Bar 每输入一个字,就会听到小 Foo 全方位的“指导”。于是小 Bar 用了一个方法,每次自己停下来思考的时候,小 Foo 就会指导他。
1 | function debounce(fn, interval = 300) { |
这个方法叫做函数防抖
,可用于:搜索框实时显示(不需要每输入一个字都进行一次搜索)
小Foo和小Bar的故事还在继续……
朱耀华_20180913