七天学会NodeJS(三)进程管理(util.format、Process、Child Process、Cluster)、子进程父进程之间通讯、异步编程、异常处理、域(Domain)

本文深入探讨NodeJS的进程管理,包括util.format、Process、Child Process、Cluster,以及子进程间的通讯。同时,文章还详细阐述了NodeJS的异步编程,包括回调、代码设计模式和异常处理,特别是如何利用Domain模块简化异常处理。通过实例展示了如何获取命令行参数、退出程序、控制输入输出以及创建和管理子进程。此外,还介绍了如何处理异步编程中的回调地狱和异常陷阱。
摘要由CSDN通过智能技术生成

七天学会NodeJS(三)进程管理(util.format、Process、Child Process、Cluster)、子进程父进程之间通讯、异步编程、异常处理、域(Domain)

总结:

  • 进程管理

    • 本章小结

      • 使用process对象管理自身
      • 使用child_process模块创建和管理子进程
    • util.format(format, […])

      • 根据第一个参数,返回一个格式化字符串,类似printf的格式化输出。
      • 第一个参数是一个字符串,包含零个或多个占位符。 每一个占位符被替换为与其对应的转换后的值。 支持的占位符有:
        • %s - 字符串.
        • %d - 数字 (整型和浮点型).
        • %j - JSON. 如果这个参数包含循环对象的引用,将会被替换成字符串 '[Circular]'
        • %% - 单独一个百分号('%')。不会消耗一个参数。
      • 如果占位符没有相对应的参数,占位符将不会被替换。
    • Proces

      • 官方文档: http://nodejs.org/api/process.html

      • 在NodeJS中,可以通过process对象感知和控制NodeJS自身进程的方方面面。

      • process不是内置模块,而是一个全局对象,因此在任何地方都可以直接使用。

      • 如何获取命令行参数

        • 在NodeJS中可以通过process.argv获取命令行参数
        • 由于argv[0]固定等于NodeJS执行程序的绝对路径,argv[1]固定等于主模块的绝对路径。
        • 第一个命令行参数从argv[2]开始
      • 如何退出程序

        • 正常退出状态码=0
        • 捕捉异常后退出 process.exit(1)
      • 如何控制输入输出

        • NodeJS程序的标准输入流(stdin)、一个标准输出流(stdout)、一个标准错误流(stderr)分别对应process.stdinprocess.stdoutprocess.stderr
        • 第一个是只读数据流,后边两个是只写数据流
      • 子进程父进程之间通讯

        • /* parent.js  这是父进程*/
          //父进程在创建子进程,在options.stdio字段中通过ipc开启了一条IPC通道,之后就可以监听子进程对象的message事件接收来自子进程的消息
          var child = child_process.spawn('node', [ 'child.js' ], {
                      
                  stdio: [ 0, 1, 2, 'ipc' ]
              });
          
          child.on('message', function (msg) {
                      
              console.log(msg);
          });
          
          //通过.send方法给子进程发送消息
          child.send({
                       hello: 'hello' });
          
          /* child.js  这是子进程*/
          //在子进程这边,可以在process对象上监听message事件接收来自父进程的消息
          process.on('message', function (msg) {
                      
              msg.hello = msg.hello.toUpperCase();
              //并通过.send方法向父进程发送消息。
              process.send(msg);
          });
          
    • Child Process

      • 官方文档: http://nodejs.org/api/child_process.html
      • 使用child_process模块可以创建和控制子进程。
      • 该模块提供的API中最核心的是.spawn,其余API都是针对特定使用场景对它的进一步封装,算是一种语法糖。
        • 使用.spawn(exec, args, options)方法,创建子进程,该方法支持三个参数。
        • 第一个参数是执行文件路径,可以是执行文件的相对或绝对路径,也可以是根据PATH环境变量能找到的执行文件名。
        • 第二个参数中,数组中的每个成员都按顺序对应一个命令行参数。
        • 第三个参数可选,用于配置子进程的执行环境与行为。
    • Cluster

      • cluster模块是对child_process模块的进一步封装,专用于解决单进程NodeJS Web服务器无法充分利用多核CPU的问题。
      • 使用该模块可以简化多进程服务器程序的开发,让每个核上运行一个工作进程,并统一通过主进程监听端口和分发请求。
  • 异步编程

    • 本章小结

      • 不掌握异步编程就不算学会NodeJS。
      • 异步编程依托于回调来实现,而使用回调不一定就是异步编程。
      • 异步编程下的函数间数据传递、数组遍历和异常处理与同步编程有很大差别。
      • 使用domain模块简化异步代码的异常处理,并小心陷阱。
    • 简介

      • NodeJS最大的卖点——事件机制和异步IO,对开发者并不是透明的。
    • 回调

      • 你不知道用户何时单击按钮。 因此,为点击事件定义了一个事件处理程序。 该事件处理程序会接受一个函数,该函数会在该事件被触发时被调用:

        document.getElementById('button').addEventListener('click', () => {
                  
          //被点击
        })
        

        这就是所谓的回调。回调是一个简单的函数,会作为值被传给另一个函数,并且仅在事件发生时才被执行

      • 我们仍然回到JS是单线程运行的这个事实上,这决定了JS在执行完一段代码之前无法执行包括回调函数在内的别的代码。也就是说,即使平行线程完成工作了,通知JS主线程执行回调函数了,回调函数也要等到JS主线程空闲时才能开始执行。

    • 异常处理

      • 在NodeJS中,几乎所有异步API都按照以下方式设计,回调函数中第一个参数都是err。因此我们在编写自己的异步函数时,也可以按照这种方式来处理异常,与NodeJS的设计风格保持一致。

      • function async(fn, callback) {
                  
            // Code execution path breaks here.
            setTimeout(function () {
                  
                try {
                  
                    callback(null, fn());
                } catch (err) {
                  
                    callback(err);
                }
            }, 0);
        }
        
        async(null, function (err, data) {
                  
            if (err) {
                  
                console.log('Error: %s', err.message);
            } else {
                  
                // Do something.
            }
        });
        
        -- Console ------------------------------
        Error: object is not a function
        
      • 回调函数已经让代码变得复杂了,而异步方式下对异常的处理更加剧了代码的复杂度。如果NodeJS的最大卖点最后变成这个样子,那就没人愿意用NodeJS了,因此接下来会介绍NodeJS提供的一些解决方案。

    • 域(Domain)

      • 官方文档: http://nodejs.org/api/domain.html

      • 可以简化异步代码的异常处理

      • 为了让代码好看点,我们可以在每处理一个请求时,使用domain模块创建一个子域(JS子运行环境)。在子域内运行的代码可以随意抛出异常,而这些异常可以通过子域对象的error事件统一捕获。

        function async(request, callback) {
                  
            // Do something.
            asyncA(request, function (data) {
                  
                // Do something
                asyncB(request, function (data) {
                  
                    // Do something
                    asyncC(request, function (data) {
                  
                        // Do something
                        callback(data);
                    });
                });
            });
        }
        
        http.createServer(function (request, response) {
                  
            var d = domain.create();
        
            d.on('error', function () {
                  
                response.writeHead(500);
                response.end();
            });
        
            d.run(function () {
                  
                async(request, function (data) {
                  
                    response.writeHead(200);
                    response.end(data);
                });
            });
        });
        

1. 进程管理

NodeJS可以感知和控制自身进程的运行环境和状态,也可以创建子进程并与其协同工作,这使得NodeJS可以把多个程序组合在一起共同完成某项工作,并在其中充当胶水和调度器的作用。本章除了介绍与之相关的NodeJS内置模块外,还会重点介绍典型的使用场景。

开门红

我们已经知道了NodeJS自带的fs模块比较基础,把一个目录里的所有文件和子目录都拷贝到另一个目录里需要写不少代码。另外我们也知道,终端下的cp命令比较好用,一条cp -r source/* target命令就能搞定目录拷贝。那我们首先看看如何使用NodeJS调用终端命令来简化目录拷贝,示例代码如下:

var child_process = require('child_process');
var util = require('util');

function copy(source, target, callback) {
   
    child_proces
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChrisP3616

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值