Javascript 函数在使用回调返回数据后仍然捕获来自其他函数的错误

Javascript 函数在使用回调返回数据后仍然捕获来自其他函数的错误,javascript,Javascript,对javascript来说相当陌生。我调用一个函数并发送一些数据。函数通过回调返回数据。然后,我将数据发送到另一个包含错误的函数。不知何故,错误被捕获在第一个函数的CATCH块中。我以为第一个函数在回调之后就完成了。我不明白错误是如何返回到第一个函数的CATCH块的 var数据1=1; 让myMessage=document.querySelector('.fiddleMessage'); myMessage.value=''; //主要功能 函数myFunc1(myData,回调){ myM

对javascript来说相当陌生。我调用一个函数并发送一些数据。函数通过回调返回数据。然后,我将数据发送到另一个包含错误的函数。不知何故,错误被捕获在第一个函数的CATCH块中。我以为第一个函数在回调之后就完成了。我不明白错误是如何返回到第一个函数的CATCH块的

var数据1=1;
让myMessage=document.querySelector('.fiddleMessage');
myMessage.value='';
//主要功能
函数myFunc1(myData,回调){
myMessage.innerHTML='myFunc1-输入Try block';
试一试{
myData+=1;
myMessage.innerHTML+='
myFunc1-myData='+myData; //回调以发送结果 if(回调类型==“函数”){ myMessage.innerHTML+='
myFunc1-返回带有回调的数据'; 返回(回调(myData)); //无法访问下一条消息 myMessage.innerHTML+='
myFunc1-回调后'; } }捕捉(错误){ myMessage.innerHTML+='
myFunc1-在CATCH块中'; myMessage.innerHTML+='
'+错误; log('myFunc1-in CATCH block'); 控制台日志(err); //将消息发送回调用函数 如果(错误){ if(回调类型==“函数”){ myMessage.innerHTML+='
myFunc1-在catch块中-在回调中'; var errorMessage=“dataError”; 回调(错误消息); } } } } //函数来做一些处理 函数myFunc2(myData2){ myMessage.innerHTML+='
myFunc2-myData2='+myData2; //使用错误的名称在此处导致错误 //在下一行中,“结果”应为“myData2” //错误将被发送回myFunc1到CATCH块-为什么? myMessage.innerHTML+='
myFunc2-在此处导致错误'; var data3=myResult+=1; //var data3=myData2+=1; 返回数据3; } //调用myFunc1 myFunc1(数据1,函数(结果){ myMessage.innerHTML+='
调用myFunc1-result='+result; 如果(结果==“数据错误”){ myMessage.innerHTML+='
调用myFunc1-收到数据错误'; }否则{ myMessage.innerHTML+='
调用myFunc1-调用myFunc2'; var data2=myFunc2(结果); } });
h1{
颜色:#f00;
}
函数退出回调
此测试旨在证明函数在回调后不会关闭。将数据发送到函数,回调返回数据,然后发送到另一个有错误的函数,错误被捕获到第一个函数的CATCH块中



您可能觉得奇怪,但代码中最后一个结束的函数是第一个调用的函数
myFunc1

您的回调几乎没有意义,因为您没有执行任何异步代码。(对于异步代码,可以在主函数完成处理后启动回调)

当JavaScript引擎遇到错误时,它会向上移动当前堆栈,直到找到错误处理程序(在本例中,它位于第一个调用的函数中)。如果找不到错误处理程序,错误将传播到窗口对象(您将在控制台中看到它,它可能会破坏您的代码)


此外,您正在调用回调函数并向其传递一个值,您希望它返回一些内容(它将以静默方式返回
未定义的
,因为回调中没有
return
语句)。

您可能觉得奇怪,但是在代码中结束的最后一个函数是第一个调用的函数
myFunc1

您的回调几乎没有意义,因为您没有执行任何异步代码。(对于异步代码,可以在主函数完成处理后启动回调)

当JavaScript引擎遇到错误时,它会向上移动当前堆栈,直到找到错误处理程序(在本例中,它位于第一个调用的函数中)。如果找不到错误处理程序,错误将传播到窗口对象(您将在控制台中看到它,它可能会破坏您的代码)


另外,您正在调用回调函数并向其传递一个值,您希望它返回一些内容(它将以静默方式返回
未定义的
,因为回调中没有
返回
语句)。

这就是异常处理的工作方式。错误被抛出到
myFunc2
中,并且没有被捕获到,因此它会沿着调用堆栈向上传播。由于在
myFunc1
中的
try
块中调用了
myFunc2
,因此执行了那里的
catch
子句。任何异常都可以在调用堆栈中实际发生点之上的任何位置捕获(从异常发生点向上移动的第一个这样的点确实“捕获”了它,因此停止了传播)。只有当我们到达堆栈顶部的全局范围时,错误才会实际打印到控制台,并且如果没有在那里捕获到错误,执行就会终止


另外,我注意到您说过“我以为第一个函数在回调之后就完成了”。事实显然并非如此。第一个函数在其
return
语句之后结束,但由于您返回回调的返回值,因此在回调完成之前,它不会结束。

这就是异常处理的工作方式。错误被抛出到
myFunc2
中,并且没有被捕获到,因此它会沿着调用堆栈向上传播。由于在
myFunc1
中的
try
块中调用了
myFunc2
,因此执行了那里的
catch
子句。任何异常都可以在调用堆栈中实际发生点之上的任何位置捕获(从异常发生点向上移动的第一个这样的点确实“捕获”了它,因此停止了传播)。只有当我们到达堆栈顶部的全局范围时,才会出现错误
return (callback(myData));
let temp = callback(myData);
return temp;