Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

回调函数 #19

Open
HarleyWang93 opened this issue Apr 8, 2018 · 0 comments
Open

回调函数 #19

HarleyWang93 opened this issue Apr 8, 2018 · 0 comments

Comments

@HarleyWang93
Copy link
Owner

在 JavaScript 中我们常听说回调函数,回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。通俗来说,回调函数就是就是一个可执行的函数,在需要的地方调用它。

我们知道,对象可以作为参数传递给函数,而函数实际上也是对象,那么函数也可以作为参数传递给函数,在实际使用中,我们可以很容易找到回调函数的例子,例如 jQuery 中

$('div').click(function(){     
  console.log('hello')   
})

其实 click 中的 function 就是个匿名的回调函数,当然,回调函数也可以是具名的

$('div').click(callback)
function callback(){
  console.log('hello')
}

这个回调函数不会立即执行,在传参的过程中,此时传入了回调函数的指针,它并不会立即执行,而是需要等到被调用的时候才会执行。

关于回调函数的 this

在回调函数调用时 this 的执行上下文并不是回调函数定义时的那个上下文,而是调用它的函数所在的上下文。

例如:

var obj = {
	sum: 0,
	add: function(num1, num2){
		this.sum = num1 + num2;
	}
};
function add(num1, num2, callback){
	callback(num1, num2);
};
add(1,2, obj.add);
console.log(obj.sum);			//=>0
console.log(window.sum);		//=>3

上述代码调用回调函数的时候是在全局环境下,因此 this 指向的是 window,所以 sum 的值是赋值给 window 的。

允许多重回调函数

一个典型的例子就是 jQuery 中 ajax 的使用

function successCallback(){
    //在发送之前做点什么
}     
function successCallback(){
  //在信息被成功接收之后做点什么
}
function completeCallback(){
  //在完成之后做点什么
}
function errorCallback(){
    //当错误发生时做点什么
}
$.ajax({
    url:"http://xxx.com/",
    success:successCallback,
    complete:completeCallback,
    error:errorCallback
})

通过回调函数获取数据

在进行跨域的时候,我们需要获取对应接口的数据并对数据进行相应的处理,那么就可以通过接口所提供的回调函数通过传参来获取数据。

例如 JSONP 跨域时,提供的接口为 http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4

<script>
  function func(data){
    console.log(data)   //  获取数据
  }
</script>
<script src="http://platform.sina.com.cn/slide/album_tech?jsoncallback=func&app_key=1271687855&num=3&page=4"></script>

一个回调函数中可以嵌入另一个回调函数,对于这种情况出现多层嵌套时,代码会难以阅读和维护,这个时候可以采用命名回调函数的方式调用,或者采用模块化管理函数。

异步编程

我们知道,JavaScript 的执行模式分为两种,异步(Asynchronous)和同步(Synchronous),同步模式指的是代码按照顺序自上而下执行,生活中排队就是同步的一个例子,异步模式指的是代码顺序与执行顺序不保证一致,就好比正好好排队的时候,突然有一个人插队了,这就是异步。但是在浏览器端,异步模式是很重要的,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是 Ajax 操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有 http 请求,服务器性能会急剧下降,很快就会失去响应。而回调函数就是实现异步编程的一个方式。

定时器就是异步实现的一个例子。

var a = 1
setTimeout(function () {
  console.log(a)   // a打印出来是多少呢? 
}, 1000)

我们看到 1s 之后传入一个匿名的回调函数,并打印出 a 的值,你也许会说,a 是 1 。可是你怎么知道后续的 a 会不会被修改呢?假如 a 的值在 1000 行的代码处被修改为 233 或者其他的值,此时 a 的值就不确定了,不管是 setTimeout,还是 setInterval,当我们没有完整的看完代码——也就是代码在之后执行的时候没有确定 a 的值的时候,a 在 1s 后的值在目前的代码片段是无法确定的,异步编程的特点在于当前可执行的代码不阻塞后面代码的执行,而回调函数是实现异步编程的基本方法。

除了定时器,还有事件监听、http 请求、promise 对象中使用回调函数都可以实现异步编程。

推荐阅读

理解与使用Javascript中的回调函数

Javascript异步编程的4种方法

@HarleyWang93 HarleyWang93 changed the title 浅谈JavaScript中的回调函数 回调函数 Apr 8, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant