了解node.js中的try-and-catch

了解node.js中的try-and-catch,node.js,error-handling,Node.js,Error Handling,我不熟悉编码。试图理解为什么try…catch不应该在node.js中工作。我已经创建了一个示例,但与预期相反,请尝试…catch似乎起到了作用。我的理解错在哪里?请帮忙 function callback(error) { console.log(error); } function A() { var errorForCallback; var y = parseInt("hardnut"); if (!y) { throw new Error("bo

我不熟悉编码。试图理解为什么try…catch不应该在node.js中工作。我已经创建了一个示例,但与预期相反,请尝试…catch似乎起到了作用。我的理解错在哪里?请帮忙

function callback(error) { console.log(error); }
function A() {
    var errorForCallback;
    var y = parseInt("hardnut");
    if (!y) {
        throw new Error("boycott parsley");
        errorForCallback = "boycott parsley for callback";
    }
    setTimeout(callback(errorForCallback),1000);
}

try {
    A();
}
catch (e) {
    console.log(e.message);
}
// Output: boycott parsley
// Synchronous behaviour, try...catch works
------阅读下面的答案后,重新构建示例以反映我的理解-----

function callback(error) { console.log(error); }
function A() {
    var errorForCallback;
    setTimeout(function(){
        var y = parseInt("hardnut");
        if (!y) {
            // throw new Error("boycott parsley");
            errorForCallback = "boycott parsley for callback";
        }
        callback(errorForCallback);         
    }, 1000);

}
try {
    A();
}
catch (e) {
    console.log(e.message);
}
// Output: boycott parsley for callback
// Asynchronous behaviour
// And if "throw new Error" is uncommented, 
// then node.js stops

try-catch方法可以完美地处理同步代码。并非所有在Node.js中进行的编程都是异步的,因此在您编写的同步代码中,可以完美地使用try-catch方法。另一方面,异步代码不是这样工作的

例如,如果有两个这样的函数执行

var x = fooSync();
var y = barSync();
您可能会想到三件事,首先,只有在fooSync完成后才会执行barSync,并且您可能会想到x将包含在执行barSync之前执行fooSync返回的任何值。此外,如果fooSync抛出异常,则永远不会执行barSync

如果您想在fooSync周围使用try-catch,您可以保证,如果fooSync失败,您可以捕获该异常

现在,如果您有这样一个代码,条件将完全改变:

var x = fooAsync();
var y = barSync();
现在想象一下,当在这个场景中调用fooAsync时,它实际上并没有被执行。只是计划稍后执行。这就好像节点会有一个todo列表,此时它正忙于运行当前模块,当它发现这个函数调用时,它只会将它添加到todo列表的末尾,而不是运行它

所以,现在您不能保证barSync会在fooAsync之前运行,事实上,它可能不会。现在,您不需要控制执行fooAsync的上下文

因此,在调度fooAsync函数之后,它会立即执行barSync。那么,foosync可以返回什么呢?现在什么都没有,因为它还没有运行。所以上面的x可能是未定义的。如果您将try-catch放在这段代码周围,那么它将毫无意义,因为函数将不会在这段代码的上下文中执行。稍后,当Node.js检查todo列表中是否有任何挂起的任务时,将执行该命令。它将在另一个不断检查todo列表的例程的上下文中执行,而这唯一的执行线程称为事件循环

如果函数foosync失败,它将在运行事件循环的线程的执行上下文中失败,因此不会被try-catch语句捕获,此时,上面的模块可能已经完成了执行

因此,这就是为什么在异步编程中,您既不能获取返回值,也不能期望执行try-catch,因为您的代码是在其他地方计算的,在另一个上下文中,与您认为调用它的上下文不同。就好像你本可以做这样的事情:

scheduleForExecutionLaterWhenYouHaveTime(foo);
var y = barSync();

这就是异步编程需要其他技术来确定代码最终运行时发生了什么的原因。通常,这是通过回调通知的。您定义了一个回调函数,该函数将被回调,其中包含失败的内容或函数生成的内容的详细信息,然后您可以对此做出反应。

try-catch方法可以完美地处理同步代码。并非所有在Node.js中进行的编程都是异步的,因此在您编写的同步代码中,可以完美地使用try-catch方法。另一方面,异步代码不是这样工作的

例如,如果有两个这样的函数执行

var x = fooSync();
var y = barSync();
您可能会想到三件事,首先,只有在fooSync完成后才会执行barSync,并且您可能会想到x将包含在执行barSync之前执行fooSync返回的任何值。此外,如果fooSync抛出异常,则永远不会执行barSync

如果您想在fooSync周围使用try-catch,您可以保证,如果fooSync失败,您可以捕获该异常

现在,如果您有这样一个代码,条件将完全改变:

var x = fooAsync();
var y = barSync();
现在想象一下,当在这个场景中调用fooAsync时,它实际上并没有被执行。只是计划稍后执行。这就好像节点会有一个todo列表,此时它正忙于运行当前模块,当它发现这个函数调用时,它只会将它添加到todo列表的末尾,而不是运行它

所以,现在您不能保证barSync会在fooAsync之前运行,事实上,它可能不会。现在,您不需要控制执行fooAsync的上下文

因此,在调度fooAsync函数之后,它会立即执行barSync。那么,foosync可以返回什么呢?现在什么都没有,因为它还没有运行。所以上面的x可能是u 没有定义。如果您将try-catch放在这段代码周围,那么它将毫无意义,因为函数将不会在这段代码的上下文中执行。稍后,当Node.js检查todo列表中是否有任何挂起的任务时,将执行该命令。它将在另一个不断检查todo列表的例程的上下文中执行,而这唯一的执行线程称为事件循环

如果函数foosync失败,它将在运行事件循环的线程的执行上下文中失败,因此不会被try-catch语句捕获,此时,上面的模块可能已经完成了执行

因此,这就是为什么在异步编程中,您既不能获取返回值,也不能期望执行try-catch,因为您的代码是在其他地方计算的,在另一个上下文中,与您认为调用它的上下文不同。就好像你本可以做这样的事情:

scheduleForExecutionLaterWhenYouHaveTime(foo);
var y = barSync();

这就是异步编程需要其他技术来确定代码最终运行时发生了什么的原因。通常,这是通过回调通知的。您定义了一个回调函数,该函数会被回调,其中包含失败的细节,或者您的函数产生了什么,然后您可以对此做出反应。

为什么您认为它不应该在node.js中工作?对于异步任务引发的异常,它不起作用。如果您想捕获这些类型的错误,您可以研究使用。为什么您认为它不应该在node.js中工作?对于异步任务引发的异常,它不起作用。如果您想捕获这些类型的错误,可以研究使用。感谢您的详细解释。基于这种理解,我重新构建了我的示例。如果我取消注释抛出新错误…,那么node.js将停止。是因为它试图在try之外抛出一个错误吗?“throw”类似于“return”,因为函数中不再有代码在它之后执行。当你抛出这里时,你阻止了回调被调用。非常清晰的解释。但我想知道的是,并非所有在Node.js中进行的编程都是异步的。除了回调/同步库之外,节点何时同步执行代码?感谢您的详细解释。基于这种理解,我重新构建了我的示例。如果我取消注释抛出新错误…,那么node.js将停止。是因为它试图在try之外抛出一个错误吗?“throw”类似于“return”,因为函数中不再有代码在它之后执行。当你抛出这里时,你阻止了回调被调用。非常清晰的解释。但我想知道的是,并非所有在Node.js中进行的编程都是异步的。除了回调/同步库,节点何时同步执行代码?