什么是回调函数
编程分为两类:系统编程(system programming)和应用编程(application programming)。所谓系统编程,简单来说,就是编写库;而应用编程就是利用写好的各种库来编写具某种功用的程序,也就是应用。系统程序员会给自己写的库留下一些接口,即API(application programming interface,应用编程接口),以供应用程序员使用。所以在抽象层的图示里,库位于应用的底下。
当程序跑起来时,一般情况下,应用程序会时常通过API调用库里所预先备好的函数。但是有些库函数(即中间函数)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。中间函数和回调函数是回调的两个必要部分,不过人们往往忽略了回调里的第三位要角,就是中间函数的调用者。绝大多数情况下,这个调用者可以和程序的主函数等同起来,但为了表示区别,我这里把它称为起始函数。
链接:https://www.zhihu.com/question/19801131/answer/27459821
来源:知乎
简单来说,回调函数可以解释为“If you call me, I will call you back.” 起始函数调用中间函数,中间函数又需调用作为参数传入的回调函数。
由于nodejs的程序是异步的,想进行阻塞式编程顺序执行,可以借助callback函数实现。通常网络通信、读写文件、与数据库交互等 IO操作 会使用回调函数,需要消耗一些时间才能返回结果。
Nodejs中的回调函数
下面展示了最简单的回调函数,其中x作为回调函数被中间函数y调用
let x=function(){
console.log("i am called from inside a function")
};
let y=function(callback){
console.log('do something');
callback();
}
y(x);
运行结果:
do something
i am called from inside a function
再看一个例子:
// getTodos函数定义
const getTodos = function(callback){
setTimeout(function(){ //调用应用层的setTimeout函数,并传入callback函数
console.log('运行了3s');
console.log('2');
callback('回调函数');
console.log('运行完毕');
},3000);
};
console.log('1')
// 执行getTodos函数,并传入callback函数
getTodos(function(data){
console.log(data);
});
console.log('3')
程序运行后输出结果为:
1
3
运行了3s
2
回调函数
运行完毕
想要的结果为:1 => 运行3s => 2 => 3
因此需要将下面的函数放到回调函数中,修改为:
// getTodos函数定义
const getTodos = function(callback){
setTimeout(function(){ //调用应用层的setTimeout函数,并传入callback函数
console.log('运行了3s');
console.log('2');
callback('回调函数');
console.log('运行完毕');
},3000);
};
console.log('1')
// 执行getTodos函数,并传入callback函数
getTodos(function(data){
console.log(data);
console.log('3') // 放进回调函数中
});
运行后输出结果为:
1
运行了3s
2
回调函数
3
运行完毕
总结:执行callback函数作用:实现阻塞式编程,按顺序执行原程序与callback函数
Callback hell
在编写 js 程序时,有时候会需要几个回调函数嵌套,不仅程序看起来臃肿,也大大增大了代码的维护难度,被称为"回调地狱"(Callback hell)。如下图所示,是个经典的 Callback hell(回调地狱):