您现在的位置是:亿华云 > 数据库
给女朋友讲了讲 V8 引擎的“回调函数”!
亿华云2025-10-04 03:25:27【数据库】4人已围观
简介回调函数相信大家并不陌生,但是对于女朋友来说比较陌生,要想给女朋友讲明白回调函数是怎么回事,为什么要这样设计,使用回调函数应该注意什么,确实不容易,所以有了这篇文章。在 JavaScript 中,我个
回调函数相信大家并不陌生,回调函数但是朋友对于女朋友来说比较陌生,要想给女朋友讲明白回调函数是讲讲怎么回事,为什么要这样设计,回调函数使用回调函数应该注意什么,朋友确实不容易,讲讲所以有了这篇文章。回调函数
在 JavaScript 中,朋友我个人觉得理解回调函数,讲讲就有助于我们理解 JavaScript 中的回调函数其它设计,比如异步编程、朋友消息循环、讲讲一些常用到的回调函数 Web API 以及 Node 中的异步,这些都与回调函数息息相关,朋友所以咱们一步步的讲讲来学习和使用。
废话不多说,直接上干货!
什么是回调函数?
回调函数也是函数的一种,回调函数与普通函数的区别在于它的调用时机。所谓的回调函数是把一个函数当作另一个函数的参数,并在这个函数的源码下载某个时机进行调用,我们就将这个传入的函数称为回调函数。
回调函数分为同步回调和异步回调。它俩的区别在于调用的位置不同。
1. 同步回调
所谓的同步回调函数是在执行的函数内部被调用的。举个例子:
function fn(){ console.log("我是同步回调函数"); } function bar(f){ f(); } bar(fn);我们声明了一个回调函数 fn,我们传入 bar 函数,我们在 bar 内部调用了 fn,此时就是同步调用。
2. 异步回调
而异步回调函数是在执行的函数外部被调用的。如下代码:
function fn(){ console.log("我是异步回调函数"); } settimeout(fn, 1000);上述代码中,settimeout 的第一个参数 fn 是传入的一个回调函数,当程序执行 1000 ms 的时候,此时这个回调函数被调用,而且是在 setTimeout 函数外部被调用的云服务器,我们称 fn 为异步回调函数。
JS 线程架构
上述的问题理解起来非常简单,尤其是同步回调函数。但是对于异步回调函数什么时候被调用的,是在什么位置被调用的,我们目前是非常模糊的。
所以要想知道异步回调函数的调用时机和位置,我们需要理解 JS 的线程架构,比如消息队列、事件循环,从根上理解 JS 是如何设计这些东西的。
JS 的最初设计是单线程的,所谓的单线程就是同一时间只能干一件事情,而且 JS 运行的这个单线程就是亿华云页面的 UI 线程,毕竟 JS 为了能够更方便的操作 DOM 嘛。
那么问题来了,当我们把 JS 设计到 UI 页面线程,就会出现一个问题,当用户通过页面交互产生一个事件时,如果当前的线程正在处理其他的任务,那么这个交互事件需要等当前 UI 线程的任务处理完毕才能被处理,所以这样设计比较鸡肋。
如果当前 UI 线程一直执行其他任务,那么这个用户的交互事件任务一直不被处理,会出现页面点击无效的假象。
谷歌 V8 团队为了解决这个问题,那么就引入了消息队列。
消息队列
有了消息队列,我们把所有产生的事件,无论是 JavaScript 产生的事件还是用户点击页面交互产生的事件,都统一按照先后循序放到消息队列中,那么 UI 线程就不断的循环这个消息队列,有任务就取出来去执行。
有了消息队列之后,这个主线程就可以有序的执行各种事件任务了。
异步任务什么时候调用?
还是上述的 setTimeout 异步回调函数的例子,假如当前线程在消息队列中取出 setTimeout 这段代码执行,发现 fn 这个任务是在 1000 ms 后执行的,1000 ms 过后,主线程就会将 fn 封装成一个事件任务扔到消息队列中去等待被执行。
等消息队列中的执行到一定的时机,就会取出这个被封装过的 fn 回调函数任务,在主线程中被执行。
这个理解起来并不是很难,但是有一类回调函数比较特殊。当主线程在消息队列中取出一个网络下载的任务时,网络下载比较耗时,我们不可能让它在主线程中阻塞其他任务执行,所以主线程就会交给网络线程去执行这个下载任务,然后主线程回继续有序的在消息队列中取出其他任务执行。
此时网络线程会接受到这个任务执行下载操作,当网络线程把文件下载完毕之后,就将下载的结果封装成一个事件任务,放入到消息队列中。当主线程执行到这个任务时,就知道网络线程已经下载完了,然后将下载的结果呈现给用户。
最后
好了,今天主要和大家分享了 JavaScript 中回调函数的由来和异步回调函数的设计,这也是 V8 引擎中的一小部分,接下来会通过这样一个个的知识点,挖掘 V8 谷歌引擎的各个方面的优秀设计方案。
很赞哦!(1615)
站长推荐
评估域名涉及的行业规模与发展状况成正比。
开发者该用单一代码库还是多代码库管理代码?
浅谈一下 MyBatis 批量插入的 3 种方法!
微软正式发布 C# 10,支持.NET 6 和 Visual Studio 2022 (附更新内容大全)
用户邮箱的静态密码可能已被钓鱼和同一密码泄露。在没有收到安全警报的情况下,用户在适当的时间内不能更改密码。在此期间,攻击者可以随意输入帐户。启用辅助身份验证后,如果攻击者无法获取移动电话动态密码,他将无法进行身份验证。这样,除非用户的电子邮件密码和手机同时被盗,否则攻击者很难破解用户的邮箱。
程序员应知应会之数据库设计的那些事儿
1.5 万 Star!程序员的“网络瑞士军刀”!
MySQL性能调优,应该掌握这一个工具!!!