一、引入
我们知道js都是单线程的,也就是说同一时间,只能执行一个函数,但是js的某些操作需要间隔一段时间,比如发送一个ajax请求。为了提高程序的效率,我们开创了异步操作。具体参考我的另一篇博客:https://blog.csdn.net/konghouy/article/details/83317909 但是我们怎么知道异步操作是否结束呢?这就需要使用回调函数。
二、内容
1.什么是回调函数?
在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
说的通俗一点,就是函数不是马上执行,而是满足了某种条件后,执行相关的代码。比如:点击事件需要执行的函数,就是一个回调函数。当用户点击了元素,触发执行了函数,这个函数就是回调函数。
2.回调函数的意义
使用回调函数,进不同的事件绑定不同的回调函数,这样可以实现对不同的操作,进行不同的相应。同时,通过异步操作,让程序本需要等待网络磁盘的时间,利用起来,先执行其他函数,当异步操作结束后,再执行回调函数(不能立即执行回调函数是因为,回调函数需要应用异步操作的数据,但是其他代码不需要异步操作的支持,所以可以提前执行),通过这种方式大大提高了程序的效率。
3.回调函数应用场景
- 异步ajax操作
function Ajax(object) {
xhr = new XMLHttpRequest();
var message = getParmer(object.data);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
var status = xhr.status;
if (status >= 200 && status < 300) {
object.success(xhr.responseText,xhr.responseXML);
} else {
object.fail(xhr.status);
}
}
};
if (object.type == 'get') {
xhr.open("get", object.url + "?" + message,object.async);
xhr.send(null);
} else if(object.type == 'post'){
xhr.open("post", object.url, object.async);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(message);
}
}
function getParmer(data) {
var arr = [];
for (var thing in data) {
arr.push(encodeURIComponent(thing) + '=' + encodeURIComponent(data[thing]));
}
return arr.join('&');
}
封装的ajax,里面onreadystatechange对应的函数就是一个回调函数。当ajax发送异步请求后,需要等待后台返回的数据,这时使用回调函数就可以提高效率。
-
定时器的添加
定时器对应的函数,也是回调函数,它的触发条件是,到达了需要执行的时间
-
事件绑定
事件绑定的函数都是回调函数,当事件被触发的时候,回调函数才会执行
三、深入
function a() {
var c = 10;
setTimeout(function () {
console.log(c);
}, 100)
}
var c = 20;
a();
//打印的结果是 10
回调函数是在包含它的函数中定义,尽管回调函数没有被明确返回到上一级函数中,但回调函数被隐式的保存在内存的其他位置,依然存在。回调函数的作用域链依然保存着上一级函数的AO,这意味着回调函数本质上是一个闭包。
正如我们所知,闭包能够进入包含它的函数的作用域,因此回调函数能获取包含它的函数中的变量,以及全局作用域中的变量。