✨从异步讲起,时间,时间,请给函数以答案!

2022-11-07 17:12:15 浏览数 (1)

探秘 JS 异步

JavaScript 除了“闭包”这个最经典的设计之外,还有它是“单线程”的设计,一样可奉为最经典!

这里先抛出 3 个经典的问题:

  1. “JavaScript 为什么要是单线程?”
  2. “JavaScript 的单线程,意味着什么?”
  3. “JavaScipt 异步原理是怎么实现的?”

如果你能清晰准确地回答出这3个关于异步老生常谈的经典问题,可以跳过下一小节的释义。

经典 3 问

先浅答一下 JS 异步经典 3 问 ~

“JavaScript 为什么要是单线程?”

答:四字概括,为了:“简单方便”。JavaScript 最初设计只是运行在浏览器的脚本语言,若同一时间要做多件事情便会产生矛盾;不像其它后端语言用“锁”这样一个机制,也为了极致简单,所以 JavaScript 设计是单线程的。

“JavaScript 的单线程,意味着什么?”

答:单线程意味着任务需要排队,任务是一个接一个地执行,前一个执行完毕,才会执行下一个。这就意味着前一个任务的执行会阻塞后续任务的执行。

好比去银行办理业务,目前只有一个人工窗口,前面有个人要办理大额贷款业务,需要填写很多表格,只有等这人把全部表格都填完,整个流程都走完,才能让后面的人接着办业务。

现实中如果发生这样的事,肯定要被投诉,哪有这样设计的?让后面这么多人干等他填表格,并且这个时候窗口服务也是停止的,那效率得多低呀。

所以,正确的做法是,先将这个人挪到一边,让他去填表格,把窗口服务腾出来给后面的人继续办业务,等表格填完了,再回过头来给你办理大额贷款。

将这个比喻映射到 JavaScript 也是同样的逻辑,JavaScript 通过异步来解决单线程阻塞的问题。这也是 与生俱来 就已经设定好了的(和闭包一样,都写在 DNA 里)。

“JavaScipt 异步原理是怎么实现的?”

答:JS 引擎通过混用 2 种内存数据结构:栈和队列 来实现异步。栈与队列的交互也就是大家所熟知的 JS 事件循环(Event Loop)。

简单来讲:所有同步任务都是在主线程上执行的,形成 执行栈,异步任务的回调消息形成 回调队列。在执行栈中的任务处理完成后,主线程就开始读取任务队列中的任务并执行。按这个规则,不断往复循环。

上一张经典的图:

这里的 Stack 就相当于是前面所提银行场景中的唯一人工窗口,Stack 里面的任务就是等待办业务的人,遇到办大额贷款、填很多表格的人,则先挪到一边去,然后继续处理后面人的业务。若这人表格全填完了,就把这个消息放到 CallBack queue 里,等 Stack 里为空后,再去拿 callBack queue 的消息,继续为你解决大额贷款。

以上三问,老生常谈,温故知新。

新 3 问

好了,老 3 问只是开始的小结,这里本瓜要问异步新 3 问:

  1. “JavaScript 实现异步有哪几种表现形式?”
  2. “JavaScript 异步和函数式有什么关系?”
  3. “JavaScript 异步真的简单吗?”

在脑袋里面简单过一过你的答案?

。。。。。。

下面来逐一详细解答~~

异步演进

“JavaScript 实现异步有哪几种表现形式?”

答:

① 回调函数

最简单实现异步就是使用回调函数。

打个比方,以打电话给客服为例,你有两种选择:排队等待客服接听 或 选择客服有空时回电给你。

后面一种就是回调 —— CallBack

0 人点赞