javascript - 使用 Node.js,是否有一些语义可以告诉我代码何时要离开当前堆栈?

标签 javascript node.js error-handling

现在,我的 try/catch block 是否能正常工作对我来说还是个谜。我围绕代码设置它们,然后,因为代码中的某些内容是“异步的”,这似乎是在操作系统级别 fork 到另一个线程/进程的一种奇特方式,如果 try/catch 发生在其中,则会被忽略代码。

我对此很好,我只是想知道是否有一些迹象表明这一点?按照惯例,我明白,如果一个电话要求回调,它是异步的,否则不是。我明白为什么回调意味着异步,但恐怕反过来并不总是正确的:没有什么能阻止我用一个 try/catch 包围一个调用,它被加载到一个新的调用堆栈中,也不会要求回调。这对我来说似乎真的很困惑,如果可能的话,我希望对我的 try/catches 有更多的控制,而不是使用所有未捕获的异常都由其处理的默认回调。

  1. 是否有语义来告诉我代码何时离开 当前堆栈?

更新:这是一个例子:

var UserSchema = new mongoose.Schema({
  email: {type: String, unique: true},
  password: String,
  firstName: String,
  lastName: String,
  created_at: {type: Date, default: Date.now},
  updated_at: Date
});


var User = mongoose.model('User', UserSchema);

var users = [
  {email: 'foo@bar.com', firstName: 'Justin', lastName: 'Jones'},
  {email: 'foo@bar.com', firstName: 'Justin', lastName: 'Jones'}
];


users.forEach(function(user) {

          var newUser = new User(user);
          newUser.save(function(err, obj) {

            if (!err) console.log("Saved: ", obj.email);

          });

});

鉴于上面的代码,无法在 save() 内部捕获异常,因为它发生在另一个调用堆栈中。有没有什么办法可以让我从外部知道调用 save() 时会发生什么?

更新:每个告诉我为此使用处理程序的人都应该阅读 this ?它明确建议不要处理未在其“线程执行”中捕获的异常,因为它仅充当线程。

最佳答案

“异步”不是“ fork 到另一个线程/进程的奇特说法”。

JavaScript 是单线程的。故事结局。在语言层面没有 fork 。

“异步”的意思就是它所说的:执行顺序不是代码的顺序。一些代码——回调函数——将在特定事件发生时的某个时间点执行。它是一种基于事件的编程模型。

考虑这个简单的例子:

function hello () { alert("Hello!"); }

setTimeout(hello, 2000);

这是最基本形式的异步回调。您有一个回调处理程序 - 函数 hello - 和一个事件生成器,在本例中是一个基于时间的生成器。

一旦事件发生(已经过了 2 秒),就会调用回调处理程序。

现在进行修改:

function hello() { alert(foo.bar); }

try {    
  setTimeout(hello, 2000);
} catch (ex) {
  alert(ex.message);
}

我们围绕 setTimeout 引入了一个 try-catch block 。它保护回调的注册,仅此而已。这一步很可能会成功,因此 try-catch block 永远不会做任何事情。回调本身 将在 2 秒后失败这一事实自然不会影响 try-catch block 。这是您感到困惑的行为。

现在进行另一个修改:

function hello() { 
  try {    
    alert(foo.bar); 
  } catch (ex) {
    alert("foo.bar is not defined");
  }
}

setTimeout(hello, 2000);

现在 try-catch block 保护实际上可能失败的步骤。这意味着您必须在可能发生错误的地方使用 try-catch block ,而不是通常将它们包裹在程序的大部分周围(这似乎是您所做的)。

但是如何获得异常来做一些有用的和可配置的事情呢?自然地,通过引入更多回调。

function hello(onError) { 
  try {    
    alert(foo.bar); 
  } catch (ex) {
    onError("foo.bar is not defined", ex);
  }
}

function errorHandler(customMessage, exception) {
  alert(customMessage);
  // or do something with exception 
}

setTimeout(function () {
  hello(errorHandler)
}, 2000);

根据您添加的示例:

var saveUsers = function(users, onSuccess, onError) {
  users.forEach(function(user) {
    var newUser = new User(user);

    newUser.save(function(err, obj) {
      if (err) {
        onError(err, obj);
        return false;
      } else {
        onSuccess(obj);
      }
    });
  });
}

var users = [
  {email: 'foo@bar.com', firstName: 'Justin', lastName: 'J'},
  {email: 'foo@bar.com', firstName: 'Justin', lastName: 'J'}
];

saveUsers(
  users, 
  function (user) { console.log("Saved: ", user.email); },
  function (err, user) { console.log("Could not save: ", user.email); }
});

关于javascript - 使用 Node.js,是否有一些语义可以告诉我代码何时要离开当前堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10304634/

相关文章:

node.js - 如何在调用服务器方法时处理连接超时

sql - 如何识别类型转换专栏的错误?

javascript - 实时网络库 - 用 socket.io 或什么替换 hookbox?

javascript - 将 $.when()/$.promise() 与内部具有 AJAX 的函数一起使用

node.js - 转发端口从 80 和 443 到 8080

javascript - 填充二维数组 "line by line"JavaScript/NodeJS

java - 在Spring Boot中的异常处理期间保留自定义MDC属性

javascript - 需要 JS 和 LESS

javascript - 将图像插入数组

node.js - 如何处理 Node js 应用程序错误以防止崩溃