关于 js 中的回调函数 callback

本文写于1年前 曾经的学习文章现在拿出来分享

前言程序员

其实我一直很困惑关于js中的callback,困惑的缘由是,学习中这块看的资料少,可是平时又常常见,偶尔复制一下前人代码,功能实现了也就再也不去追其起因,这么着,这个callback的概念就愈来愈混乱,由于你总感受它是你Ajax请求后调用的那个函数,又感受它是你某一个函数中的形参而已,而当你有一天看到一点关于Node.js的代码后你会更加崩溃,由于你会发现不少的callback,可是这么着下去确定是不行的,由于不少的东西若是只是知道概念和理论,没有实践出结果,没有思考和感觉,这些东西永远不是你的,因此任何关于技术上用到的东西都应该去花时间钻研一下,学习 付出时间 实践都会搞明白的,还会沉淀不少思想,因此最近一直在浏览相关的文章和资料,本身在项目中也用到了一些去实践,这样一轮下来后,你会发现明亮了不少设计模式

一 .搞清楚异步和同步

异步async/同步sync数组

举个小栗子浏览器

1.早上起来不论你是先刷牙仍是先洗脸,都要等一个事情完毕后才能进行下一项,这就是一个同步的例子多线程

2.而后刷牙的时候你也能够烧水喝 (不用等你刷完牙)这就是一个异步的例子异步

来段异步代码示例async

js里面最基础的异步实现

运行结果

以上代码会先执行函数a,并且不会等到a中的延迟函数执行完才执行函数b, 在延迟函数被触发的过程当中就执行了函数b,当js引擎的event 队列空闲时才会去执行队列里等待的setTimeout的回调函数,这就是一个异步的例子

题外话

调用 setTimeout 函数会在一个时间段过去后在队列中添加一个消息。这个时间段做为函数的第二个参数被传入。若是队列中没有其它消息,消息会被立刻处理。可是,若是有其它消息,setTimeout 消息必须等待其它消息处理完。所以第二个参数仅仅表示最少的时间 而非确切的时间

因此即便,时间设置为0,也是会照样先执行函数b

来段同步代码示例


运行结果为1

print函数会等change函数完成以后去执行,因此结构输出为1,由于change函数修改了全局变量a的值,change执行以后才执行的print函数

二.回调函数究竟是什么

A callback is a function that is passed as an argument to another function and is executed after its parent function has completed.

以上解释是Google得出的解释,很是清晰简明,有时候我以为英文理解要比翻译成中文二次理解更清楚

来看几个经典的回调函数代码,我敢保证你必定用过他们

异步请求的回调函数

点击事件的回调函数

数组中遍历每一项调用的回调函数

同步回调的例子

因此回调与同步、异步并无直接的联系,回调只是一种实现方式,既能够有同步回调,也能够有异步回调,还能够有事件处理回调和延迟函数回调,这些在咱们工做中有不少的使用场景

因此其实并非咱们不认识回调函数,而是咱们都萦绕在了这个“callback“ 这个词上,当你在一个函数中看到它是就会困惑,其实它只是一个形参名字而已函数

三.为何写回调函数学习

看了以上的简单介绍以后,是否是对callback再也不陌生和以为神秘,因此尽情的去使用吧,线程

1.关于回调函数和js单线程以及js异步机制

咱们都知道js是单线程的,这种设计模式给咱们带来了不少的方便之处,咱们不须要考虑各个线程之间的通讯,也不须要写不少烧脑的代码,也就是说js的引擎只能一件一件事的去完成和执行相关的操做,因此全部须要执行的事情都像排队同样,等待着被触发和执行,但是若是这样的话,若是在队列中有一件事情须要花费不少的时间,那么后面的任务都将处于一种等待状态,有时甚至会出现浏览器假死现象,例如其中有一件正在执行的一个任务是一个死循环,那么会致使后续其余的任务没法正常执行,因此js在同步机制的缺陷下设计出了异步模式

在异步执行的模式下,每个异步的任务都有其本身一个或着多个回调函数,这样当前在执行的异步任务执行完以后,不会立刻执行事件队列中的下一项任务,而是执行它的回调函数,而下一项任务也不会等当前这个回调函数执行完,由于它也不能肯定当前的回调合适执行完毕,只要引它被触发就会执行,举个例子

图片资源还未请求完毕

上图能够看到,我要购买一个东西,当我点进物品的详情页以后,图片资源还未请求完毕,而此时我就能够点击add to cart, 发起另外一个请求,js任务列表中的添加购物车事件就会开始执行,它的执行也不会干扰到图片资源的请求任务,这也是异步执行机制的妙处

2.js的单线程浏览器内核的多线程

说到js的单线程,顺便再了解一下关于浏览器内核的多线程,关于浏览器工做原理此处不作讲解,由于本身研究的不深刻,等待研究学习研究透彻再分享

浏览器常驻三大线程: js引擎线程,GUI渲染线程,浏览器事件触发线程

看到此图你是否是会豁然开朗许多,由于浏览器是一个多线程的执行环境,在浏览器的内核中分配了多个线程,最主要的线程之一便是js引擎的线程,同时js事件队列中的异步请求,交互事件触发,定时器等事件都是由浏览器的事件触发线程进行监听的,浏览器的事件触发线程被触发后会把任务加入到js 引擎的任务队列中,当js 引擎空闲时候就会开始执行该任务

完结

以上就是本篇文章的所有内容,由对回调函数的陌生到熟悉和使用,以及对同步/异步的概念,还有js的执行机制以及浏览器内核的多线程机制相信你们都有了一个简单的知识脉络,但愿经过此文提到的内容,每一个小伙伴去查阅更深刻的资料,于此同时我也会不断的去修缮,因此咱们不能作一个知其然而不知其因此然的程序员,要有充分的好奇心去学习它,带着学习让咱们受益的心态去作和研究本身感兴趣的东西是一件很是快乐的事情,但愿我能够把个人快乐带给每一位看文章的小伙伴,也但愿你多多给我提出意见,让咱们一块儿在学习的路上共同发现和成长,2107年欢迎你和我一块儿作一个不断努力学习的知识分子

Cayley 一个不断努力学习的女程序员

相关文章
相关标签/搜索