回调函数可以用来处理 JavaScript 的异步操作,但是选用 Promise、async/await 更好,因为多重回调函数会导致回调地狱。
回调函数不是**同步的**,它是延时操作执行完毕后会被调用的一个函数。
比如全局方法 “setTimeout” ,它第一个参数就是一个回调函数,第二个参数是等待的时间(以毫秒为单位),如下:
function callback() {console.log("I am the first");}setTimeout(callback, 300);console.log("I am the last");// output// I am the last// I am the first
300毫秒之后,回调函数 callback 会被调用。但是在它完成前,剩下的代码会继续往下运行,所以 “I am the last” 会被先打印出来。
开发者常犯的一个错误是误以为回调函数是同步的。比如,他们会把回调函数的返回值用在其他操作上。
例如下面这个错误:
function addTwoNumbers() {let firstNumber = 5;let secondNumber;setTimeout(function () {secondNumber = 10;}, 200);console.log(firstNumber + secondNumber);}addTwoNumbers();// NaN
会输出 “NaN” ,因为 “secondNumber” 还未被赋值。在 “firstNumber + secondNumber” 被执行的时候,”secondNumber” 还没有被赋值,因为 “setTimeout” 函数要在 “200毫秒” 后才调用回调函数。
最好的解决办法是把剩下的代码放在回调函数里去执行:
function addTwoNumbers() {let firstNumber = 5;let secondNumber;setTimeout(function () {secondNumber = 10;console.log(firstNumber + secondNumber);}, 200);}addTwoNumbers();// 15