js回调函数的使用

在第一次学js的时候,估计很多人对回调函数很蒙,今天有空梳理总结下回调函数,算是一次学习,算是一次总结,也算是一次分享。

回调函数执行流程

fun是被调用的函数,在调用fun函数时传递一个被回调的函数callback,1、2、3、4为执行步骤,箭头指向为调用。
在这里插入图片描述
执行流程:
1)在代码中,fun首先被执行
2)fun函数执行,js的执行转移到fun函数内部,fun函数内部的语句从上往下执行
3)在fun函数中调用callback
4)在调用fun函数时传入的函数(callback)被执行
5)执行callback函数中的内容

回调小demo

如果把上面的流程转换成简单的代码它是这样的

function fun(callback){
	console.log("fun执行");
	callback();// 调用过程可以传递参数
}

function sayHello(){
	console.log("callback:hello world")
}

//把sayHello当做但是传递给fun函数
fun(sayHello);

//执行结果
fun执行
callback:hello world

匿名函数简写方式

function fun(callback){
	console.log("fun执行");
	callback();// 调用过程可以传递参数
}

// 调用
fun(function(){
	console.log("回调执行了")
});

// es6
fun(()=>{
	console.log("回调执行了")
});

// 输出
fun执行
回调执行了

我们知道js中的对象有基本数据类型(Number、String…)、函数、数组这几类,是对象就可以当做参数进行传递,当我们把一个函数当做参数传递给函数时,这个函数就称为一个回调函数,根据这个判断,当我们调用js方法时,括号中如果出现function或者箭头函数,则说明咱们传递的就是一个回调函数。

回调算是一种程序的设计模式,在java中也有回调函数,那些类名常常包含Handler的类就是java中传递的匿名对象,JDK8的升级带来了lambda,Java中那些能用lambda代替的匿名对象都是Java的回调方法,例如接口实现线程的run方法就是很经典的回调。

js中回调无处不在

一些常见的回调。

# ajax请求回调
$.post({
	url: "https://xxxx.com/api/xxx",
	dataType:"json",
	data:{},
	// 回调 es6
	success: res=>{
		// TODO
	},
	// 回调
	error: err =>{
		// TODO
	}
});

# 数组方法
let arr = [0,1,2];
arr.forEach(function(item,index){
	// TODO
});

# jQuery事件回调
$("#btn").click(function(){
	// TODO
})

# promise中的回调
new Promise(
  function (resolve, reject) {
    // 一段耗时的异步操作
    resolve('成功') // 数据处理完成
    // reject('失败') // 数据处理出错
  }
).then(
  (res) => {console.log(res)},  // 成功
  (err) => {console.log(err)} // 失败
)

除了以上这些还有我们在vue中见到的各种生命周期钩子函数也是回调,回调在js这门语言中用到了出神入化,现在,我们应该反观为什么js中用了那么多回调函数?
一些原因:
1)javascript是典型的函数式编程语言,顺应其特点,在js中才会出现这么多回调函数
2)“回调”这种编程语言的组织和设计模式是很优秀的
3)回调函数使用特别灵活,通过可以拿回函数内部的数据,可以进行异步的处理(特别是在ajax请求)等

使用回调函数注意事项

当回调是一个使用this对象的方法时,我们要改变下调用回调函数的方式来保持this对象上下文。否则当回调传给一个全局函数的时候,this对象将会指向全局window对象。或者它会指向包含这个方法的对象。

let outerThis = this;
$.ajax({
    url: this.data.app.BASE_URL + "/calendar/setRemind",
    method: "POST",
    dataType: "json",
    data: { },
    success: res => {
		// 此处的this指向包含success_callback的ajax函数
		// 在这里通常用 outerThis 外部的this
    },
});

如果是自己函数中用到了回调。我们可以通过使用Call或者Apply函数执行callback来解决解决之前的问题,这两个方法用于设置函数中的this对象并且传入参数。

Call把第一个参数的值用于函数内的this对象,然后剩下的参数独立地传给函数(通过逗号分隔)。Apply函数也是把第一个参数的值用于函数内的this对象,第二个参数是一个传给对象的数组(或者arguments对象)。

// 这里我们为回调对象加了个参数this_obj
function fun(callback, this_obj)  {
    // 其他操作

    // 用apply函数把this指向callbackObj
    callback.apply (this_obj, [data1, data2]);
}

// 使用
let outerThis = this;
fun((data1,data2)=>{
	// 此时 this等于outerThis
},this);

参考
https://www.zcfy.cc/article/understand-javascript-callback-functions-and-use-them-javascript-is-sexy
https://juejin.im/post/6844903987771097102
https://www.cnblogs.com/moltboy/archive/2013/04/24/3040213.html


想了解作者更多,请移步我的个人网站,欢迎交流、留言~
极客技术空间:https://elltor.com/

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值