回调是在JavaScript中理解的一个非常重要的主题。在本文中,我们将看到什么是回调以及如何使用它们。
什么是回调
首先,我们将看到一个常规的javascript函数,并从那里将看到如何使用回调。
常规Javascript函数
因此,首先让我们看一下javascript中的正常函数。
function multiply(a, b) {
var result = a * b;
console.log("multiply Function Result:",result);
}
multiply(2, 4);
这里我们有一个简单的函数,将两个数字相乘。然后,我们使用输入2和4调用该函数。
回调示例1
现在想象一下在乘法计算结果后是否必须立即运行另一个操作。这是我们使用回调的地方。下面的代码显示了这一点。
function multiply(a, b, callback) {
var result = a * b;
console.log("multiply Function Result:",result);
callback(result);
}
function checkOddEven(result){
var isEven = result % 2 == 0
if(isEven){
console.log('checkOddEven Function:',result,' is Even');
}
else
{
console.log('checkOddEven Function:',result,' is Odd');
}
}
multiply(7, 9, checkOddEven);
在乘法函数中,我们接受回调以及输入。
当我们调用乘法函数时,我们将回调传递为checkOddEven。因此,基本上,回调不过是一个函数。checkOddEven是用于检查数字是奇数还是偶数的函数。
最后,在乘法函数中,我们有callback(result)。这是我们要求回调函数执行的地方。
所以在上面的代码中,顺序如下
- 首先,我们调用乘法函数并传递checkOddEven作为回调
- 乘法函数执行并计算乘法结果
- 一旦计算出结果,乘法函数就会要求回调执行。
- 在这种情况下,回调是checkOddEven函数。因此,checkOddEven函数将执行。
上面代码的结果如下所示
multiply Function Result: 63
checkOddEven Function: 63 is Odd
我们可以将任何函数传递给回调。
回调示例2
让我们看下面的脚本
function multiply(a, b, callback) {
var result = a * b;
console.log("multiply Function Result:",result);
callback(result);
}
function checkPosNeg(result){
var isPositive = result >= 0;
if(isPositive){
console.log('checkPosNeg Function:',result,' is Positive');
}
else
{
console.log('checkPosNeg Function:',result,' is Negative');
}
}
multiply(-7, 9, checkPosNeg);
在这里,我们有一个名为checkPosNeg的函数,该函数检查数字是正数还是负数。
在此示例中,我们将回调作为checkPosNeg传递。
上面程序的输出如下
multiply Function Result: -63
checkPosNeg Function: -63 is Negative
从此示例中,我们看到可以将任何函数传递给callback。
匿名回叫功能
传递回调的另一种方法是使用匿名函数。如下所示。
function multiply(a, b, callback) {
var result = a * b;
console.log("multiply Function Result:", result);
callback(result);
}
multiply(-7, 9, function(result) {
if (result > 0) {
console.log('checkPosNeg Function:', result, ' is Positive');
} else {
console.log('checkPosNeg Function:', result, ' is Negative');
}
});
在这种情况下,我们看到回调函数是在调用乘法函数的同时创建的。此函数基本上检查数字是正数还是负数,但是该函数没有任何名称。
回调中的错误处理
以下代码段显示了如何在回调中进行错误处理。
function divide(a, b, callback) {
if (b != 0) {
var result = a / b;
console.log('divide Function Result', result);
callback(null, result);
} else
callback(new Error('Divide by 0 Error:' + a + '/' + b))
}
function checkPosNeg(error, result) {
if (error) {
console.log('checkPosNeg Function cannot run');
console.log(error);
} else {
var isPositive = result >= 0;
if (isPositive) {
console.log('checkPosNeg Function:', result, ' is Positive');
} else {
console.log('checkPosNeg Function:', result, ' is Negative');
}
}
}
divide(4, 0, checkPosNeg);
在这种情况下,我们有一个函数调用的鸿沟具有回调checkPosNeg。
现在,当b为0时,则无法进行除法。如果无法进行除法,则我们无法将任何结果发送到回调。
因此,在这种情况下,我们将回调函数定义为checkPosNeg(error,result)。
只要有可能进行除法,我们就调用callback(null,result)表示没有错误,一切都很好。
如果无法进行除法,则我们调用callback(new Error(’Error message’)),它告诉您存在错误。
现在在checkPosNeg函数中,我们还需要检查错误。如果error不为null,那么我们需要在代码中采取必要的措施。例如,这里我们只是打印错误消息。
为什么我们需要回调
您可能会想到的一个明显问题是,为什么我们甚至需要回调。
让我们看下面的代码片段
console.log('Task1');
makeServerCall(url,function(error,result){
console.log('Task2');
});
console.log('Task3');
在上面的代码中,首先打印Task1。
接下来的makeServerCall函数进行网络调用。
现在任务3之前或之后进行打印任务2?
通常,每当我们进行网络呼叫时,代码都会继续执行下一条语句,而不会等待结果同步。
因此,在进行网络调用的那一刻,代码将继续执行下一条语句并显示Task3。
一旦网络呼叫完成并且响应返回,则将打印Task2。
因此,此处makeServerCall将回调作为其输入。因此,一旦服务器调用完成,它将执行回调。
在这种情况下,回调使我们能够在网络调用完成后运行某些操作,而不会阻塞代码(即,在网络调用完成之前,不会阻塞将来的语句)。
回调回调
回调可以链接在一起。
采取以下代码段。
function1(input1, function(error, result1) {
function2(result1, function(error, result2) {
function3(result2, function(error, result3) {
console.log('Callback Chain')
})
})
})
- 在这里,首先我们等待function1完成网络调用并执行第一个回调。
- 第一个回调依次调用function2。一旦function2完成其网络调用,它将执行第二个回调。
- 第二个回调调用function3。一旦function3完成其网络调用,它将执行第三个回调。
- 第三个回调仅打印一条消息。
也可以将更多的回调链接在一起。
这里似乎没有东西
嗯,就像您在上面的脚本中可能已经注意到的那样,随着回调次数的增加,它变得有点难以理解。
上面的示例仅显示了单行功能。如果函数稍大,链接回调的数量更多,则代码将高度不可读。同样,这意味着调试代码非常非常困难。
这里有一个样本片段来说明这一点
function1(input1, function(error, result1) {
if (error) {
console.log('Error')
} else {
function2(result1, function(error, result2) {
if (error) {
console.log('Error')
} else {
function3(result2, function(error, result3) {
if (error) {
console.log('Error')
} else {
function4(result3, function(error, result4) {
if (error) {
console.log('Error')
}
})
}
})
}
})
}
})
这个问题被称为厄运金字塔。
解决此问题的一种方法是使用Promises,我将在以后的文章中介绍
恭喜😄
现在,您知道什么是回调以及如何使用它们。
快乐编码😄