正在阅读 Web Worker 的相关介绍,从中理解了回调函数(CallBack)的概念。
虽然可能不全面,但是先记着,因为从这里就解开了我一个大疑惑,也就是回调函数跟“普通函数”的区别是什么。之后查阅更多相关内容再梳理,现在只是想把这个大的思维突破给记着,不然又要忘记。也先不要管描述有没有技术细节上的错误,这里先把关注点放在理清回调函数机制上,因为顾虑太多的话,就不是这篇文章“只想记录一下这个概念”的主旨了,同时也会使得问题越想越复杂。
首先,回函函数是需要要在涉及“任务”、“消息”、“队列”、“并发”等这类非单一执行线路(线程、进程啥的)的环境下讨论的,这就是一个大区别。
假设现在有两个线程,一个主线程A,一个子线程B,在子线程中维护着一个任务队列,队列中有任务X、Y、Z。
主线程A一直在运行着,然后它要等待子线程B的消息,如果B想要执行队列中的任务X,那么,B就把X指定的回调函数CBhello()的相关信息发给A,然后A就调用CBhello()来执行。
这里就是主要区别,也就是它为什么叫“回调”的原因,因为这里不是A直接去调用CBhelo()的(“普通函数”就是这样),而是B先把这个它想要执行的函数告诉A,让A“帮它执行”。
其实就是它“接收一个函数”,而不是“调用一个函数”去执行,主被动不同。
[补充]
刚好昨晚看到讲异步的东西,联系了一下,顺便把下边这个例子讲一下。
(明明它是在讲异步的东西,但是我偏偏能联想到回调函数的关键之处,而且梳理之后感觉理论上还很合拍,说明了回调函数的产生真的是因为“非单一执行线路”/“异步”的需要?)
语言是 JavaScript
function fun(num1,num2,callback) //子线程上
{
var num = num1 + num2;
callback(num); //这里执行任务X
}
function print(num)
{
console.log("the sum is :"+num);
};
fun(1,2,print); //主线程上
把上边的代码对照这句话:如果子线程B想要执行队列中的任务X,B就把X指定的回调函数CBhello()的相关信息发送给主线程A,然后A就调用CBhello()来执行。
这里先不要把目光放在这个“相关信息发送给主线程A”这个发送动作,这里其实是另一种情况,“触发”(因为手头暂时没有想到其它例子),具体可以了解I/O中断相关知识点。任务X就是输出sum,X指定的回调函数是print()。当子线程执行的fun()函数执行到任务X的时候,也就是它想输出sum,这时,它就“触发”回调函数callback,实际上是callback去定义了这个任务X,我们是上帝视角根据后边代码来讲任务X是想输出sum,所以其实这时候这个callback暂时还只是一个“占位”,它需要主线程来具体调用,这个例子中,主线程上执行的fun()中具体调用了callback,也就是调用刚才说的任务“输出sum”指定的回调函数print()。
end