浅谈javascript回调函数


Posted in Javascript onDecember 07, 2014

把函数作为参数传入到另一个函数中。这个函数就是所谓的回调函数

经常遇到这样一种情况,某个项目的A层和B层是由不同的人员协同完成.A层负责功能funA,B层负责funcB。当B层要用到某个模块的数据,于是他对A层人员说,我需要你们提供满足某种需求的数据,你给我提供一个接口。

A层的人员说:我给你提供数据,怎么展示和处理则是B的事情。
当然B层不可能为你每个需求都提供一个数据接口,B给A提供一个通过的接口.B得到数据,然后B写函数去展示。

即,你需要和其他人合作,别人提供数据,而你不需要关注别人获取或者构建数据的方式方法。你只要对这个拿到的数据进行操作。这时候就需要使用回调函数

因此,回调本质上是一种设计模式,并且jQuery(包括其他框架)的设计原则遵循了这个模式。

一个同步(阻塞)中使用回调的例子,目的是在func1代码执行完成后执行func2。

var func1=function(callback){

    //do something.

    (callback && typeof(callback) === "function") && callback();

}
func1(func2);

    var func2=function(){

}

异步回调的例子:

$(document).ready(callback);
    $.ajax({

        url: "test.html",

        context: document.body

    }).done(function() { 

        $(this).addClass("done");

    }).fail(function() { 

        alert("error");

    }).always(function() { 

        alert("complete"); 

    });

注意的是,ajax请求确实是异步的,不过这请求是由浏览器新开一个线程请求,当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理。见:http://www.phpv.net/html/1700.html

回调什么时候执行

回调函数,一般在同步情境下是最后执行的,而在异步情境下有可能不执行,因为事件没有被触发或者条件不满足。

回调函数的使用场合

资源加载:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调,图片加载完成执行回调,AJAX等等。
DOM事件及Node.js事件基于回调机制(Node.js回调可能会出现多层回调嵌套的问题)。
setTimeout的延迟时间为0,这个hack经常被用到,settimeout调用的函数其实就是一个callback的体现
链式调用:链式调用的时候,在赋值器(setter)方法中(或者本身没有返回值的方法中)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现
setTimeout、setInterval的函数调用得到其返回值。由于两个函数都是异步的,即:他们的调用时序和程序的主流程是相对独立的,所以没有办法在主体里面等待它们的返回值,它们被打开的时候程序也不会停下来等待,否则也就失去了setTimeout及setInterval的意义了,所以用return已经没有意义,只能使用callback。callback的意义在于将timer执行的结果通知给代理函数进行及时处理。

网上收集一下资料,应该弄懂了,自己整理出一个例子:

function fun(num,callback){

    if(num<0)  { 

        alert("调用A层函数处理!");

        alert("数据不能为负,输入错误!"); 

    }else if(num==0){

        alert("调用A层函数处理!");

        alert("该数据项不存在!");

    }else{

        alert("调用B层函数处理!");

        callback(1);

    }

}

function test(){

    var num=document.getElementById("score").value;

    fun(num,function(back){ //匿名B层处理函数

alert(":"+back);

        if(num<2) 

            alert("数字为1");

        else if(num<=3) 

            alert("数字为2或3!");

        else 

            alert("数字大于3!"); 

    })

 }

当函数开始执行fun的时候,先跑去找判定num是否是负数或者为零,否则执行B层处理函数alert(":"+back);输出1,判定为<2、<=3、>3等情况。

经验小提示:

最好保证回调存在且必须是函数引用或者函数表达式:
(callback && typeof(callback) === "function") && callback();

 var obj={

        init : function(callback){

        //TODO ...

        if(callback && typeof(callback) === "function") && callback()){

              callback('init...');//回调

        }

    }

最后,关于为什么要使用回调函数呢?下面的比喻很生动有趣。

你有事去隔壁寝室找同学,发现人不在,你怎么办呢?

方法1,每隔几分钟再去趟隔壁寝室,看人在不
方法2,拜托与他同寝室的人,看到他回来时叫一下你

前者是轮询,后者是回调。

那你说,我直接在隔壁寝室等到同学回来可以吗?

可以啊,只不过这样原本你可以省下时间做其他事,现在必须浪费在等待上了。把原来的非阻塞的异步调用变成了阻塞的同步调用。

JavaScript的回调是在异步调用场景下使用的,使用回调性能好于轮询。

更简单一点:

“我现在出发,到了通知你”
这是一个异步的流程,“我出发”这个过程中(函数执行),“你”可以去做任何事,“到了”(函数执行完毕)“通知你”(回调)进行之后的流程

Javascript 相关文章推荐
jQuery选择头像并实时显示的代码
Jun 27 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
Jun 19 Javascript
基于jquery步骤进度条源码分享
Nov 12 Javascript
javascript实现粘贴qq截图功能(clipboardData)
May 29 Javascript
很酷的星级评分系统原生JS实现
Aug 25 Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
Oct 17 Javascript
JavaScript在控件上添加倒计时功能的实现代码
Jul 04 Javascript
详解vue 实例方法和数据
Oct 23 Javascript
chorme 浏览器记住密码后input黄色背景处理方法(两种)
Nov 22 Javascript
在JavaScript中实现链式调用的实现
Dec 24 Javascript
JS内置对象和Math对象知识点详解
Apr 03 Javascript
vue项目配置同一局域网可使用ip访问的操作
Oct 23 Javascript
javascript实现playfair和hill密码算法
Dec 07 #Javascript
JS数组(Array)处理函数整理
Dec 07 #Javascript
浅谈JS日期(Date)处理函数
Dec 07 #Javascript
AngularJS HTML编译器介绍
Dec 06 #Javascript
AngularJS初始化过程分析(引导程序)
Dec 06 #Javascript
什么是 AngularJS?AngularJS简介
Dec 06 #Javascript
AngularJS入门教程(二):AngularJS模板
Dec 06 #Javascript
You might like
php不用正则采集速度探究总结
2008/03/24 PHP
php实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
分享3个php获取日历的函数
2015/09/25 PHP
php实现当前页面点击下载文件的实例代码
2016/11/16 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
用javascript编写的第一人称射击游戏
2007/02/25 Javascript
JavaScript中的事件处理
2008/01/16 Javascript
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
jQuery中slice()方法用法实例
2015/01/07 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
2015/04/10 Javascript
JQuery中基础过滤选择器用法实例分析
2015/05/18 Javascript
基于jquery实现左右按钮点击的图片切换效果
2021/01/27 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
2018/03/29 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
vue中的inject学习教程
2019/04/24 Javascript
vue实现编辑器键盘抬起时内容跟随光标距顶位置向上滚动效果
2020/05/28 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
JavaScript eval()函数定义及使用方法详解
2020/07/07 Javascript
初学Python函数的笔记整理
2015/04/07 Python
浅谈Python 字符串格式化输出(format/printf)
2016/07/21 Python
python批量修改ssh密码的实现
2019/08/08 Python
解决python多行注释引发缩进错误的问题
2019/08/23 Python
python 扩展print打印文件路径和当前时间信息的实例代码
2019/10/11 Python
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
Css3实现无缝滚动防抖
2020/09/14 HTML / CSS
H5 canvas中width、height和style的宽高区别详解
2018/11/02 HTML / CSS
美国正版电视节目和电影在线观看:Hulu
2018/05/24 全球购物
简历的自荐信
2013/12/19 职场文书
物业公司采购员岗位职责
2013/12/31 职场文书
房地产资料员岗位职责
2014/07/02 职场文书
学校体育节班级口号
2015/12/25 职场文书
《秦兵马俑》教学反思
2016/02/24 职场文书
小学生作文写作技巧100例,非常实用!
2019/07/08 职场文书