「这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战」
在计算机程序设计中,回调函数,或简称回调(Callback 即call then back 被主函数调用运算后会返回主函数),是指通过参数将函数传递到其它代码的,某一块可执行代码的引用。——维基百科
问题示例
假如现在有这样一个动态加载脚本的函数
function loadScript(src) {
// 创建一个 <script> 标签,并将其附加到页面
// 这将使得具有给定 src 的脚本开始加载,并在加载完成后运行
let script = document.createElement('script');
script.src = src;
document.head.append(script);
}
创建一个lodash.js文件为例
https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js
假如你想把lodash.js加载到页面,可以这样做
// 在给定路径下加载并执行脚本
loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js');
lodash.js中声明了函数_
如果你在 loadScript(…) 调用后立即执行获取这个函数,会发现这个函数未定义
这是因为脚本是“异步”调用的,也就是说,如果在 loadScript(…) 下面有任何其他代码,它们不会等到脚本加载完成才执行。所以这个时候你调用lodash.js里的函数_,会直接报错,因为此时函数还不存在。
解决方案
为了解决这个问题,我们可以添加一个callback 函数作为 loadScript 的第二个参数,该函数应在脚本加载完成时执行。
改进:
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(script); //关键代码
document.head.append(script);
}
现在,如果想要调用script.js文件中的方法,可以把方法写在回调函数中,因为回调函数会在在脚本加载完成后才执行。
loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.2.0/lodash.js', script => {
console.log(`script ${script.src} is loaded`);
console.log('脚本中声明的函数', _ );
});
运行结果:
在JavaScript中被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。
改进
上面我们并没有考虑出现 error 的情况。比如脚本加载失败了。所以我们需要改进一下,新增加载错误的处理
这个时候,如果加载成功,则调用 callback(null, script),反之调用 callback(error)
新的问题
当我们只有一个回调的时候,还没有什么,但是当回调太多时,代码就会像这样变得杂乱无章,这也就是常说的回调地狱。
所以很明显我们还需要有更好的方法来解决这个问题,其中较好的方法之一就是后面将会说到的promise。
参考资料:
Callback (computer programming)
🎨【点赞】【关注】不迷路,更多前端干货等你解锁
往期推荐