- 回调可以是同步也可以是异步
- 同步可以是单线程也可以是多线程
- 异步必须是多线程或多进程(每个进程可以是单线程) ==> 换句话说,异步必须依靠多线程或多进程才能完成
同步回调:把函数b传递给函数a。执行a的时候,回调了b,a要一直等到b执行完才能继续执行;
异步回调:把函数b传递给函数a。执行a的时候,回调了b,然后a就继续往后执行,b独自执行。
引用一段话:
你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。
接下来用ajax来解释回调函数:
场景:在一个页面中只有一个异步ajax任务,代码可以这样写
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function loadXMLDoc()
{
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
xmlhttp.send();
}
</script>
</head>
<body>
<div id="myDiv"><h2>使用 AJAX 修改该文本内容</h2></div>
<button type="button" onclick="loadXMLDoc()">修改内容</button>
</body>
</html>
注意:ajax分为同步的(open()的第三个参数为false),异步的(open()的第三个参数为true,默认的为true)。
倘若设置为false,那么当有多个ajax任务的时候,就会创建多个XHR对象,而且由于JS是单线程的,这样就是导致浏览器堵塞。
接下来这个多个异步ajax请求:
<!DOCTYPE html>
<html>
<head>
<script>
var xmlhttp;
function loadXMLDoc(url,cfunc)
{
if (window.XMLHttpRequest)
{// IE7+, Firefox, Chrome, Opera, Safari 代码
xmlhttp=new XMLHttpRequest();
}
else
{// IE6, IE5 代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function myFunction()
{
loadXMLDoc("/try/ajax/ajax_info.txt",function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
});
}
</script>
</head>
<body>
<div id="myDiv"><h2>使用 AJAX 修改文本内容</h2></div>
<button type="button" onclick="myFunction()">修改内容</button>
</body>
</html>
通过代码复用性,将loadXMLDoc函数的第二个参数设置为回调函数,对于不同的场景,修改回调函数的内容增加灵活性,第一个参数为请求的资源,同样是增加灵活性。
回调函数里面的onreadystatechange为出发调用回调函数的事件。