Node.js初学者指南 第2部分





朋友们,美好的一天!



我将继续发布此Node.js教程的翻译



其他部分:



第1

部分第2

部分第3

部分第4部分



JavaScript V8引擎



V8是Google Chrome支持的JavaScript引擎的名称。这是需要您的JavaScript代码并在浏览器中运行的东西。



换句话说,V8是JavaScript运行时。浏览器还提供DOM和其他Web API。



JavaScript引擎与浏览器无关。这就是导致Node.js出现的原因。V8在2009年被选作Node.js的引擎,并且随着Node.js的日益普及,V8已成为许多服务器端JavaScript的基础。



Node.js生态系统非常庞大,例如,借助V8,我们能够使用Electron创建桌面应用程序。



其他JS引擎


其他浏览器具有自己的JavaScript引擎:





等等



所有这些引擎都实现了ECMA ES-262(ECMAScript)标准,这是JavaScript使用的标准。



关于性能


V8用C ++编写,并且还在不断发展。它适用于所有操作系统。



我们不会介绍V8实施的细节:您可以在此处找到它们,它们有时会发生根本性的变化。



与其他JavaScript引擎一样,V8也在不断发展,以提高Web和Node.js生态系统的速度。



网上的性能竞赛已经持续了多年,并且我们(作为用户和开发人员)从竞争中受益匪浅,因为我们每年都获得更快,更优化的工具。



汇编


JavaScript通常作为一种解释语言在市场上销售,但现代引擎不只是解释JavaScript,而是对其进行编译。



自2009年在Firefox 3.5中添加SpiderMonkey JavaScript编译器以来,这种情况就一直在发生。



V8通过即时(实时,JIT,动态编译)动态地编译JavaScript,以加快其执行速度。



听起来似乎违反直觉,但是随着2004年Google Maps的出现,JavaScript已经从一种将编写少量代码块的语言演变成一种可以创建成熟应用程序的语言,这种语言由在浏览器中执行的数百或数千行代码组成。



今天,我们的浏览器应用程序可以运行数小时;它们不再是解决诸如表单验证之类的原始任务的简单工具。



在当今世界,编译JavaScript很有意义:尽管准备代码需要花费更多时间,但其性能却大大超过了解释后的代码。



从命令行运行Node.js脚本



运行Node.js程序的标准方法是运行全局命令node并传递可执行文件的名称。



如果Node.js应用程序的主文件名为app.js,则可以这样调用它:



node app.js


执行指定的命令时,请确保您位于带有文件的目录中app.js



如何退出Node.js?



有多种方法可以停止Node.js应用程序。



通过终端运行程序时,可以使用来关闭它ctrl-C,但是,让我们讨论一下编程方式。



让我们从最激进的话题开始,讨论为什么不应该使用它。



主模块(全局内核模块)process提供了一种轻松的方法来退出软件Node.js应用程序:process.exit()



当Node.js到达这一行代码时,程序的执行过程立即结束。



这意味着所有正在进行的回调,提交的请求(待处理),文件系统的开放访问,写入stdoutstderr所有这些都将被硬终止。



如果您可以接受,则可以将exit()一个整数传递给该方法-一个信号以完成代码的执行:



process.exit(1)


默认退出代码为0,表示成功。不同的退出代码具有不同的含义,您可以使用它们来确保某些程序与其他程序进行交互。



您可以在此处阅读有关退出代码的更多信息



您还可以为属性分配适当的值exitCode



process.exitCode = 1


程序完成后,Node.js将返回此代码。



所有进程完成后,程序执行将轻柔终止。



在Node.js中,我们经常启动服务器:



const express = require('express')
const app = express()

app.get('/', (req, res) => {
    res.send('Hi!')
})

app.listen(3000, () => console.log('Server ready'))


该程序将永远不会终止。如果您调用process.exit(),所有待处理或正在运行的请求将被中止。不酷。



在这种情况下,有必要发送信号命令SIGTERM并使用处理器信号处理程序对其进行处理(process您无需连接它,默认情况下可用):



const express = require('express')

const app = express()

app.get('/', (req, res) => {
    res.send('Hi!')
})

const server = app.listen(3000, () => console.log('Server ready'))

process.on('SIGTERM', () => {
    server.close(() => {
        console.log('Process terminated')
    })
})


什么是信号?信号是POSIX通信系统:通知进程已发生事件。



SIGKILL-有关立即完成该过程的信号,类似process.exit()



SIGTERM-有关过程软结束的信号。这个信号可以由过程控制系统发送如upstartsupervisord



可以通过另一功能的程序内发送此信号:



process.kill(process.id, 'SIGTERM')


或从另一个Node.js程序或系统上运行的任何其他应用程序获得,只要他们知道您要终止的进程的PID。



如何在Node.js中读取环境变量?



Node.js主模块process具有一个属性,env其中包含在进程启动时设置的所有环境变量。



这是访问默认的NODE_ENV环境变量的示例development



process.env.NODE_ENV // development


在执行脚本之前在生产中设置值将告诉Node.js它前面有一个生产环境。



以类似的方式,您可以访问任何设置的环境变量。



如何使用Node.js REPL



该命令node用于运行Node.js脚本:



node script.js 


如果省略文件名,将进入REPL模式:



node 


REPL(运行评估打印循环)是一个代码执行环境(通常是终端窗口),它接受用户输入的表达式并返回对该表达式求值的结果。



如果输入node终端,则会发生以下情况:



>


终端将进入待机模式。



更准确地说,在这种情况下,终端正在等待输入一些JavaScript代码。



我们介绍以下内容:



> console.log('test')
test 
undefined 
>


第一个值test是命令输出到控制台的undefined,然后得到返回执行值,console.log()



之后,我们可以输入其他值。



使用tab自动完成


REPL是交互式的。



如果tab在编写代码时按下,则REPL将尝试通过从先前定义的或预定义的变量中进行选择来完成已编写的内容。



JavaScript对象


尝试输入JavaScript类的名称,例如,Number添加一个句点并单击tab



REPL将显示此类的所有属性和方法:







全局对象


您可以通过键入global.并按tab以下键获取全局对象列表







特殊变量_


如果在代码末尾键入,_将显示最后一个操作的结果。



点后命令


REPL包含一些以点开头的特殊命令。他们来了:



  • .help -显示可用命令列表
  • .editor-启用用于编写多行JavaScript代码的编辑模式。要在此模式下执行代码,请按ctrl-D
  • .break-停止输入多行代码。像按ctrl-C
  • .clear -将REPL上下文重置为空对象,删除所有输入的代码
  • .load -加载位于当前(工作)目录中的JavaScript文件
  • .save -将REPL会话保存到具有指定名称的文件中
  • .exit-从REPL退出。与双击相同ctrl-C


REPL知道您正在输入多行代码而没有调用.editor



例如,如果您开始实现迭代:



[1, 2, 3].forEach(num => {


按下enter,REPL将跳到新的行,该行的开头有三个点,表示您可以继续使用代码块:



... console.log(num)
... })


如果.break最后输入,则多行代码模式将停止,并且表达式将不执行。



使用命令行传递参数



启动Node.js应用程序时,可以向其传递任意数量的参数。



参数可以是独立的,也可以是键和值。



例如:



node app.js joe


要么



node app.js name=joe 


如何在Node.js代码中检索值取决于此。



内置对象用于检索值process



argv对象的属性包含通过命令行传递的参数数组。



第一个参数是命令的完整路径node



第二个是可执行文件的完整路径。



我们感兴趣的参数从第三个位置(数组索引)开始。



您可以使用循环遍历参数(包括节点路径和文件路径):



process.argv.forEach((val, index) => {
    console.log(`${index}: ${val}`)
})


可以通过创建没有前两个参数的新数组来获取传递的参数:



const args = process.argv.slice(2)


如果我们有一个不带索引(键)的参数:



node app.js joe


我们可以这样得到:



const args = process.argv.slice(2)
args[0]


在这种情况下:



node app.js name=joe


args[0]-这name=joe就是为什么我们需要解析它。最好的方法是使用简约处理参数:



const args = require('minimist')(process.argv.slice(2))
args['name'] // joe


在这里,您需要在每个参数之前使用双破折号:



node app.js --name=joe


使用Node.js将结果输出到命令行



通过模块标准输出 console


Node.js提供了一个控制台模块,其中包含许多与命令行交互的非常有用的方法。



它看起来像一个console浏览器对象



该模块的主要方法之一是console.log(),它将输出的字符串打印到控制台。



如果传入一个对象,它将被转换为字符串。



我们可以传递console.log几个变量:



const x = 'x'
const y = 'y'
console.log(x, y)


和Node.js都将输出。



我们还可以使用说明符设置字符串格式:



例如:



console.log('My %s has %d years', 'cat', 2)


  • %s -将变量格式化为字符串
  • %d -将变量格式化为数字
  • %i -将变量转换为整数
  • %o -将变量格式化为对象


例如:



console.log('%o', Number)


清洁控制台


console.clear() 清除控制台(行为取决于所使用的控制台)。



计数元素


console.count()是一种方便的方法。



查看以下代码:



const x = 1 
const y = 2 
const z = 3
console.count(
    'The value of x is ' + x +
    ' and has been checked .. how many times?'
)
console.count(
    'The value of x is ' + x +
    ' and has been checked .. how many times?'
)
console.count(
    'The value of y is ' + y +
    ' and has been checked .. how many times?'
)


计数器对行显示的数量进行计数并显示该数字。



The value of x is 1 and has been checked .. how many times?: 1
The value of x is 1 and has been checked .. how many times?: 2
The value of y is 2 and has been checked .. how many times?: 1  


这样就可以计算出苹果和橙子的数量:



const oranges = ['orange', 'orange']
const apples = ['just one apple']
oranges.forEach(fruit => console.count(fruit))
apples.forEach(fruit => console.count(fruit))


堆栈跟踪显示


在某些情况下,例如,为了回答“我们如何到达代码的这一部分?”这个问题,有必要显示函数堆栈的踪迹。



您可以使用console.trace()



const function2 = () => console.trace()
const function1 = () => function2()
function1()


这会将堆栈跟踪信息打印到控制台。如果我们在Node.js REPL中执行以上代码,这就是我们在命令行上看到的内容:



Trace
    at function2 (repl:1:33)
    at function1 (repl:1:25)
    at repl:1:1
    at ContextifyScript.Script.runInThisContext (vm.js:44:33)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:440:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)


计算代码执行时间


您可以使用time()轻松计算函数运行了多长时间timeEnd()



const doSomething = () => console.log('test')
const measureDoingSomething = () => {
    console.time('doSomething()')
    //  -      
    doSomething()
    console.timeEnd('doSomething()')
}
measureDoingSomething()


标准输出和标准错误


众所周知,console.log非常适合将消息打印到控制台。这称为标准输出或stdout



console.error显示流stderr



该流不会输出到控制台,而是会写入错误日志。



样式输出


您可以使用转义序列将输出到控制台的文本着色这些序列是标识颜色的一组符号。



例如:



console.log('\x1b[33m%s\x1b[0m', 'hi!')


如果您在Node.js REPL中键入上面的代码,它将hi!为黄色。



所考虑的方法相当费力。使控制台输出着色的最简单方法是使用库。Chalk是这些库之一,除了定义颜色外,Chalk还允许您使文本变为粗体,斜体或带下划线。



使用npm install chalk安装库,如下所示:



const chalk = require('chalk')
console.log(chalk.yellow('hi!'))


该用途chalk.yellow比记忆复杂序列容易得多。这也使代码更具可读性。



创建进度条


Progress是一个很棒的库,用于在终端中创建进度条。使用进行安装npm install progress



该代码段创建了一个10步进度条。每100毫秒执行一个步骤。填充指标时,我们禁用计数器:



const ProgressBar = require('progress')

const bar = new ProgressBar(':bar', { total: 10 })
const timer = setInterval(() => {
    bar.tick()
    if (bar.complete) clearInterval(timer)
}, 100)


谢谢朋友们的关注。如果您发现错误和错别字,请毫不犹豫地写在PM中,我将不胜感激。



未完待续…



All Articles