# 回调函数
3 min read
Table of Contents
回调函数是将一个函数作为参数传递给另一个函数,当外部函数被调用的时候可以执行一些回调函数。
function funcA() { console.log('funcA')}
function funcB(callback) { console.log('funcB') callback()}
funcB(funcA)匿名回调函数
function funcB(function() { // ...})回调函数的作用
首先使用一个不使用回调函数的例子:
const calc = function (num1, num2, calcType) { if (calcType === 'add') { return num1 + num2 } else if (calcType === 'multiply') { return num1 * num2 }}
calc(2, 3, 'add') // 5calc(2, 3, 'multiply') // 6接下来使用回调函数:
const add = function (a, b) { return a + b}
const multiply = function (a, b) { return a * b}
const calc = function (num1, num2, callback) { return callback(num1, num2)}
calc(2, 3, add) // 5calc(2, 3, multiply) // 6回调地狱
回调函数的第一个问题就是回调地狱的问题,回调地狱就是回调函数的大量嵌套回调或者链式回调。
fs.readdir(source, function (err, files) { if (err) { console.log('Error finding files: ' + err) } else { files.forEach(function (filename, fileIndex) { console.log(filename) gm(source + filename).size(function (err, values) { if (err) { console.log('Error identifying file size: ' + err) } else { console.log(filename + ' : ' + values) aspect = values.width / values.height widths.forEach( function (width, widthIndex) { height = Math.round(width / aspect) console.log('resizing ' + filename + 'to ' + height + 'x' + height) this.resize(width, height).write( dest + 'w' + width + '_' + filename, function (err) { if (err) console.log('Error writing file: ' + err) }, ) }.bind(this), ) } }) }) }})回调地狱不仅带来阅读代码的困难性,包含了大量的嵌套与缩进和各个交错的执行顺序。同时回调函数的脆弱性,一旦指定了顺序和事件,代码会变得异常复杂,难以维护。
信任问题
回调函数的另一个问题就是信任问题。
如上述例子中:
calc(2, '3', add) // 23如上结果,并不是我们预期的结果。对于回调函数 add 我们可以改进
function add(a, b) { if (typeof a !== 'number' || typeof b !== 'number') { throw Error('Bad parameters') }
return a + b}参考链接
- MDN: callback function
- Wiki: Callback (computer programming)
- 知乎:回调函数(callback)是什么?
- callbackhell
- 《你不知道的Javascript(中)》 第2章