Node.js 解释Domain概念

Node.js 解释Domain概念

介绍: Node.js的domain模块用于捕捉未处理的错误。域提供了处理多个不同输入输出操作的方式,作为一个单一的组。如果事件触发器或回调在域中注册,当发生错误事件或抛出错误时,域对象会被通知而不会丢失错误的上下文。域错误处理程序不能替代在发生错误时关闭进程。处理抛出的错误的最安全的方式是关闭它,终止进程。建议一个典型的web服务器发送一个错误响应给抛出错误的请求,并允许其他成员在正常的时间内完成,并停止监听来自该工作进程的新请求。

未处理的错误可以使用内部绑定或外部绑定进行拦截。

  • 内部绑定: 错误事件发射器在域的run方法中执行代码。在域上下文中执行提供的函数,并且隐式地绑定在该上下文中创建的事件触发器、定时器和底层请求。可以选择传递参数给函数。
  • 外部绑定: 错误事件发射器使用其add方法将其明确添加到域中。它明确地将发射器添加到域中。如果发射器调用的事件处理程序抛出错误,或者如果发射器触发了”error”事件,它将被转发到域的”error”事件,类似于隐式绑定。这也适用于setInterval()setTimeout()返回的定时器。当回调函数被调用时,它会被域的”error”处理程序捕获。

语法: 要使用域模块,我们需要将其导入到项目目录中。语法如下:

const domain = require("domain");

注意: 根据官方的Node.js文档,这个域模块即将过时。一旦替代的API完成,这个模块将被完全弃用。现在,那些绝对需要域提供的功能的用户可以暂时信任它,但未来应该期待转移到其他解决方案。现在我们不应该尝试使用它们来编写新的代码。

域模块的域类用于为活动域对象提供路由错误和未捕获的异常。这是EventEmitter的子类。要处理捕获的错误,请监听错误事件。可以使用以下语法创建它。

const domain = require("domain");
const createdDomain = domain.create();

示例1: 这个示例将演示在Node.js中的域:

const EventEmitter = require("events").EventEmitter;
const domain = require("domain");
 
const emitterExplicit = new EventEmitter();
 
// Create a firstDomain for explicit binding
const firstDomain = domain.create();
 
firstDomain.on('error', function(err) {
   console.log("This error will be handled by 
       using firstDomain ("+err.message+")");
});
 
// Explicit binding using add method
firstDomain.add(emitterExplicit);
 
emitterExplicit.on('error',function(err) {
   console.log("This error will be handled by 
       using listener ("+err.message+")");
});
 
emitterExplicit.emit('error',new Error('listener will handle'));
emitterExplicit.removeAllListeners('error');
emitterExplicit.emit('error',new Error('firstDomain will handle'));
 
// Create secondDomain for implicit binding 
const secondDomain = domain.create();
 
secondDomain.on('error', function(err) {
   console.log("This error will be handled by 
       using secondDomain ("+err.message+")");
});
 
// Implicit binding using run method
secondDomain.run(function() {
   const emitterImplicit = new EventEmitter();
   emitterImplicit.emit('error',new Error('secondDomain 
       will handle'));   
});
 
firstDomain.remove(emitterExplicit);
emitterExplicit.emit('error', new Error('Exception error 
    message. The system may crash!'));

运行应用程序的步骤: 将以下代码写入终端以运行服务器:

node index.js

输出:

Node.js 解释Domain概念

示例2: 使用显式绑定方法创建服务器。您可以为HTTP服务器使用一个域,也可以为每个请求使用一个单独的域,req和res也在serverUsingDomain的作用域中创建。然而,最好先为每个请求创建一个单独的域,然后将req和res添加到该域中。

const domain = require('domain');
const http = require('http');
const serverUsingDomain = domain.create();
 
serverUsingDomain.run(() => {
  http.createServer((req, res) => {
 
    /* The server is created in the scope of 
    serverUsingDomain. Req, and res is also 
    created in the scope of serverUsingDomain. 
    However, it's a good idea to first create 
    a separate domain for each request and 
    then add req and res to it. */
    const reqdomain = domain.create();
    reqdomain.add(req);
    reqdomain.add(res);
    reqdomain.on('error', (error) => {
      console.error('Error', error, req.url);
      try {
        res.writeHead(500).end('Some Error occurred.');
      } catch (error2) {
        console.error('Error is sending 500', error2, req.url);
      }
    });
  }).listen(5000, () => {
   console.log("Server is running on PORT 5000");
  });
});

运行应用程序的步骤: 在终端中编写以下代码以运行服务器:

node index.js

输出:

Node.js 解释Domain概念

Domain 模块中可用的方法: 让我们来看一下 Node.js 中 domain 模块中可用的一些方法。

  • domain.create(): 它返回一个 domain 对象。Domain 类封装了活动 domain 对象的路由错误和未捕获异常的功能。
  • domain.add(emitter): 它显式地将一个 emitter 添加到 domain 中。如果 emitter 的事件处理函数抛出错误,或者 emitter 发出一个“error”事件,它将被派发到该 domain 的“error”事件,类似于隐式绑定。
  • domain.run(function): 在 domain 上下文中执行所提供的函数,并隐式地绑定事件发射器、计时器和在该上下文中创建的低级请求。您可以选择传递参数给该函数。
  • domain.bind(callback): 返回的函数是提供的回调函数的一个包装器。当调用返回的函数时,所有抛出的错误都会传播到该 domain 的“error”事件。
  • domain.intercept(callback): 该方法类似于 domain.bind(callback)。然而,它不仅捕捉到发生的错误,还捕捉到作为函数的第一个参数发送的 Error 对象。
  • domain.enter(): enter() 方法被 run()、bind() 和 intercept() 方法使用来设置活动的 domain。将 domain.active 和 process.domain 设置为该 domain,并隐式地将该 domain 推入由 domain 模块管理的 domain 栈中(有关 domain 栈的更多信息,请参阅 domain.exit())。调用 enter() 将 domain 绑定的异步调用与 I/O 操作链的起始分离开来。 ****
  • domain.exit(): exit() 方法退出当前 domain 并将其从 domain 栈中移除。
  • domain.remove(emitter): 它是 domain.add(emitter) 的反向操作。从指定的 emitter 中移除 domain 处理。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程