Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么异步代码中的错误有时会导致node.js服务器崩溃_Javascript_Node.js_Asynchronous_Error Handling_Crash - Fatal编程技术网

Javascript 为什么异步代码中的错误有时会导致node.js服务器崩溃

Javascript 为什么异步代码中的错误有时会导致node.js服务器崩溃,javascript,node.js,asynchronous,error-handling,crash,Javascript,Node.js,Asynchronous,Error Handling,Crash,我在一些网站上读到,在express.js中,“异步代码中的任何未捕获错误都可能导致HTTP服务器崩溃,从而导致DoS”。 我制作了这个示例来检查它,但是我想知道为什么如果错误发生在express回调中,服务器不会崩溃,但是如果它发生在setTimeout()函数中,服务器会崩溃 这两个例子中的错误不是都发生在异步代码中,还是其中一个不是异步的,我错了? 为什么某些异步代码中的未捕获错误会导致服务器崩溃,而其他异步代码中的错误不会导致服务器崩溃 var express = require("ex

我在一些网站上读到,在express.js中,“异步代码中的任何未捕获错误都可能导致HTTP服务器崩溃,从而导致DoS”。 我制作了这个示例来检查它,但是我想知道为什么如果错误发生在express回调中,服务器不会崩溃,但是如果它发生在setTimeout()函数中,服务器会崩溃

这两个例子中的错误不是都发生在异步代码中,还是其中一个不是异步的,我错了? 为什么某些异步代码中的未捕获错误会导致服务器崩溃,而其他异步代码中的错误不会导致服务器崩溃

var express = require("express");

var app = express();

http: app.get("/e1", (req, res, next) => {
  let p = req.query.p;
  let pn = parseInt(p, 10);

  //If the error happens here the server does not crashes
  let s = pn + y; // y does not exist, so an error occurs

  res.send("hi");
});

http: app.get("/e2", (req, res, next) => {
  let p = req.query.p;
  let pn = parseInt(p, 10);

  setTimeout(() => {
    //If the error happens here the server crashes
    let s = pn + y; // y does not exist, so an error occurs
  }, 100);

  res.send("hi");
});

app.listen(3000, function() {
  console.log("Example app listening on port 3000!");
});

如果我们想到在堆栈上运行的
throw
catch
,则可能会变得很清楚:

throw
:沿着堆栈向下移动,直到找到处理程序,然后从那里继续

catch
将错误处理程序添加到堆栈中

对于同步代码,可以将其可视化为:

 // Legend:
 -> function call
 <- function returns

 http.request -> express.handler -> [try] -> your function -> nested call -> Throw!
 <-            <-                   [catch] <-----------------------------------
这将处理错误,但只是同步错误(简化了,实际代码是)


现在我们该怎么处理呢

基本上:将每个回调包装成一个承诺(这样可以更轻松地处理异步错误):

然后,等待你做出的每一个承诺,并将所有承诺包装在一个“尝试”/
捕获”

 app.get(async (req, res) => {
   try {
      await delay(2000);
      const p = q + d;
   } catch(error) {
     res.status(500).send("whoops");
  }
});
这是因为
await
“保留堆栈”(但仅是
异步
函数中的一个函数在嵌套调用上等待,这就是为什么我们需要添加自己的
try
/
catch
,因为Express在回调调用上不等待),因此,一个嵌套的
await
ed函数中的错误将返回到我们的错误处理程序

 http.request -> express.handler -> [async] -> [try] -> nested call -> [await]
 <-                     <-               <-
 // synchronous code returned, the [async] stack will be kept
 [async] -> [try] -> nested call -> [await]

// somewhen, the promise resolves, execution coninues:
[async] -> [try] -> nested call -> Throw!
<-       <- [catch]  <--------------
http.request->express.handler->[async]->[try]->嵌套调用->[wait]
[等待]
//有时,承诺解决了,执行就结束了:
[async]->[try]->嵌套调用->抛出!

验证输入并使用try/catchExpress是否默认处理错误?那么,您是说express路由处理函数回调是同步代码?那么,为什么它在express文档中被称为回调?@v8rs不,我不是这么说。我不明白express route处理程序是如何捕捉到回调的error@v8rs由于回调call周围有一个
try{}catch(e){}
块,我仍然不理解它,我没有在快速回调中使用try-catch块,但express回调中发生的错误不会使应用程序崩溃
 const delay = ms => new Promise(res => setTimeout(res, ms));
 app.get(async (req, res) => {
   try {
      await delay(2000);
      const p = q + d;
   } catch(error) {
     res.status(500).send("whoops");
  }
});
 http.request -> express.handler -> [async] -> [try] -> nested call -> [await]
 <-                     <-               <-
 // synchronous code returned, the [async] stack will be kept
 [async] -> [try] -> nested call -> [await]

// somewhen, the promise resolves, execution coninues:
[async] -> [try] -> nested call -> Throw!
<-       <- [catch]  <--------------