函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回;
回调函数
回调函数就是一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。
回调,回调,不直接调用而是回头调用的意思。主函数的事先干完,回头再调用传进来的那个函数。刚开始看过很多博客,他们总是将回调函数解释的云里雾里,很高深的样子。
举一个别人举过的例子:约会结束后你送你女朋友回家,离别时,你肯定会说:“到家了给我发条信息,我很担心你。” 对不,然后你女朋友回家以后还真给你发了条信息。小伙子,你有戏了。其实这就是一个回调的过程。你留了个参数函数(要求女朋友给你发条信息)给你女朋友,然后你女朋友回家,回家的动作是主函数。她必须先回到家以后,主函数执行完了,再执行传进去的函数,然后你就收到一条信息了。
//定义主函数,回调函数作为参数 function A(callback) { callback(); console.log('我是主函数'); } //定义回调函数 function B(){ setTimeout("console.log('我是回调函数')", 3000);//模仿网络请求耗时操作 } //调用主函数,将函数B传进去 A(B); //输出结果 我是主函数 我是回调函数
上面的代码中,我们先定义了主函数和回调函数,然后再去调用主函数,将回调函数传进去。
定义主函数的时候,我们让代码先去执行callback()回调函数,但输出结果却是后输出回调函数的内容。这就说明了主函数不用等待回调函数执行完,可以接着执行自己的代码。所以一般回调函数都用在耗时操作上面。
回调函数的作用
js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作(异步AJAX,文件加载,动态加载html等),这时候就需要用到回调函数,否则会找不到对象(附值,函数未加载完成)。
回调函数实际用例
function loadData(callback){ let param = {}; $.ajax({ type : "GET", url : 'xxx', contentType : "application/json; charset=utf-8", data : param, dataType : "json", success : function(result) { //假设这里逻辑非常复杂xxxxx,前台代码大约100行,直接写在这里可读性太低 callback(result); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert(XMLHttpRequest.status); alert(XMLHttpRequest.readyState); alert(textStatus); } }); } function disposeResult(result){ //根据请求的结果,处理数据 console.log("请求结果是",result); } //调用 loadData(disposeResult);
loadData(disposeResult); 这里就是回调,disposeResult是实参,callback是形参,我们先调用loadData函数,等通过http网络请求 拿到我们需要的结果,再把请求结果当作参数传递给disposeResult函数去处理。
看到这里,聪明的你会不会发现ajax的success 不就是一个回调函数吗,我每天都在用ajax,为什么不懂什么是回调呢?
回调就是为了确保在网络请求耗时的情况下保证我们的代码执行有顺序的执行。
看到上述示例,你也会觉得回调也没什么用啊,我把disposeResult 函数里的代码写到 success 里去执行,效果不一样吗?是的 效果是一样的,但是你能确保你写的代码高可读,低耦合吗,一个ajax的success里我再套一个ajax,再加上前台处理的代码,一个方法上百行,过个十天半个月自己都看不懂。
高级使用
//封装一个满足多次调用的方法 function loadData(callback, param){ $.ajax({ type : "GET", url : 'http://127.0.0.1:8080/getuser', //获取用户的服务 contentType : "application/json; charset=utf-8", data : param, dataType : "json", success : function(result) { //假设这里逻辑非常复杂xxxxx,前台代码大约100行 callback(result); } }); } // 获取所有用户,给页面赋值 function dispose1(data){ console.log(data); // 你的前台业务代码 } //获取单个用户 function dispose2(data){ //这里也需要查询用户,怎么办?再写一个ajax? console.log(data); } function loadPage(){ //获取所有用户,假设id为空或者不传id就是查所有的用户 let param1 = {id: ""}; loadData(dispose1, param1); // 获取单个用户 let param2 = {id: "123"}; loadData(dispose2, param2 ); }