首先,开放分析

在最后一章我们研究Nodejs基本理论知识的理解,理论是非常重要的,在接下来的章节中,我们将控制公文逐步了解井内的模块各部分当主角是全球首次亮相。



让我们来看看官方的定义:

全局对象全局对象,这些对象在所有模块中都可用。有些是,t



这些对象在所有模块中都是可用的。事实上,有些对象不在全局作用域中,但在模块范围内——这些将被标识。

在浏览器中,顶级范围是全局范围。这意味着范围,也被称为对与错。

在节点中,这是不同的。顶级范围不是全局的。

我认为你不应该对全局对象的概念不熟悉。在浏览器中,最高级别范围是全局作用域,这意味着如果使用var在全局范围内定义变量,则该变量将被定义为全局范围。

但在NodeJS,它是不同的。最高级别的范围不是全局范围。在一个模块中,我们定义了一个var变量,它只在模块的作用域内。

在NodeJS,变量,函数或方法在一个模块中定义只适用于该模块,但可以通过该模块的外部通过出口对象的使用。

然而,在Node.js,还存在一个全球范围,即变量、函数或类,可用于没有加载任何模块。

同时,我们还定义了一些全局方法和全局类的全局对象,这在NodeJS是全局命名空间。任何全局变量、函数或对象都是对象的属性值。

在REPL运行环境,你可以观察到的细节,在全局对象的下列陈述,见下图:



我将逐一讨论安装在全局对象上的相关属性值对象。



(1)过程

过程{对象}。

过程{对象}这是一个流程对象。在后面的章节中我将详细介绍,但是我想看看API。

process.nexttick(回调)

在事件循环的下一个循环中调用这个回调函数。这不是一个简单的别名setTimeout(FN,0),这是更有效的。它通常在任何其他I/O事件触发之前运行,但也有一些例外情况。看到process.maxtickdepth下面。



回调回调函数是在事件循环的下一次循环调用。这不是一个简单的别名是setTimeout(fn,0)的功能,因为它是更有效的。

这个函数可以在任何I/O事件之前调用我们的回调函数。如果您希望在对象创建之后I/O操作发生之前执行一些操作,这个函数对您非常重要。

有很多人不理解process.nexttick Node.js使用。现在让我们看看process.nexttick以及如何使用它。



Node.js是单线程的,除了系统的IO,在事件的投票程序,只有一个事件将在同一时间处理。你可以认为是一个大事件轮询队列,在每一个时间点,系统只处理一个事件。

即使你的计算机有多个CPU内核,你不能同时处理多个事件,但这是特点使得Node.js适合我/ O的应用程序不适用于CPU运算中的应用。

在每个I/O应用程序中,只需要为每个输入和输出定义一个回调函数,它们将自动加入事件轮询队列。

当I/O操作完成后,回调函数将被触发,然后系统将继续处理其他请求。



U3000 U3000

在这种处理方式,process.nexttick()方法来定义一个动作,让它在下一事件轮询的时间点执行。让我们看一个例子,在这个例子中,有一个foo(),你要在下一个时间点给他打电话,你可以这样做。

复制代码代码如下所示:

函数(){

Console.error('foo);

}



process.nexttick(Foo);

Console.error('bar);



要运行上面的代码,从下一个终端打印的信息将看到bar的输出是在前面。

复制代码代码如下所示:

酒吧

Foo



你也可以使用setTimeout()函数看起来像相同的执行效果:

复制代码代码如下所示:

setTimeout(Foo,0);

console.log('bar);



但在内部处理机制,process.nexttick和setTimeout(fn(),0)是不同的。process.nexttick()不是一个简单的延迟,它具有更多的特性。

更确切地说,由process.nexttick定义的调用()将创建一个新的子组。在当前的堆栈,你可以执行任意操作数。但一旦netxtick被调用,函数必须返回父栈。事件轮询机制,然后等待重新加工新的事件,并如果nexttick电话被发现,一个新的堆栈将被创建。

让我们看看当我们用process.nexttick():



多事件交叉CPU操作密集型任务:

在下面的例子中,有一个计算(),我们希望这个函数尽可能长时间执行一些操作密集的任务。

但同时,我们也希望系统不受此功能受阻,需要能够响应其他事件。这种应用模式是一个单线程的Web服务的服务器,我们可以使用process.nexttick()过计算()和正常的事件响应。

复制代码代码如下所示:

var http =需要('http');

函数计算(){

复杂的计算继续执行

…

Process.nextTick (compute);

}

http.createserver(功能(REQ,RES){

res.writehead(200,{ 'content-type:中/平原});

res.end('Hello World);

})。听(5000,'127.0.0.1);

计算();



在这种模式下,我们不需要递归地调用计算()。我们只需要使用process.nexttick()定义计算()在事件循环和执行它在下一个时间点。

在这个过程中,如果一个新的HTTP请求出现,事件循环机制首先处理一个新请求,然后调用计算()。

相反,如果在递归调用中放入计算(),系统将总是被计算机()阻塞,无法处理新的HTTP请求。

当然,我们不能并行执行的真正好处在多CPU通过process.nexttick(),这是模拟同一应用程序的CPU。

(2)控制台

控制台{对象}用于打印到stdout和stderr。看到一段。

控制台{对象}用于打印到标准输出和错误输出:

U3000 U3000

复制代码代码如下所示:

console.log(你好只大熊!;

对于(控制台中的var i){

console.log(我++控制台{我});

}



将获得以下输出结果:

复制代码代码如下所示:

var =函数(){()

process.stdout.write(format.apply(这个论点)+ ');

}

函数(){()

process.stdout.write(format.apply(这个论点)+ ');

}

函数(){()

writeerror(format.apply(这个论点)+ ');

}

var =函数(){()

writeerror(format.apply(这个论点)+ ');

}

函数(对象){

VaR工具=需要('util);

process.stdout.write(util.inspect(对象)+ ');

}

var时间=函数(标签){

次{ } = Date.now()标签;

}

无功timeend =功能(标签){

VAR时间= Date.now()次{标签};

exports.log('undefined:NaNms、标签、时间);

}

函数(标签){

待办事项可能会这样做/更好地与V8的调试对象,一旦

/暴露。

新错误;

err.name = 'trace;

err.message =标签| |;

Error.captureStackTrace(呃,争论。被叫方);

Console.error(ERR。堆栈);

}

函数(表达式){

如果(!表达式){

var arr = array.prototype.slice.call(参数1);

要求('assert)。Ok(假,format.apply(这,ARR));

}

}



通过这些功能,我们基本上知道NodeJS已经加入到全球范围。事实上,相关的API控制台对象只是一个更先进的封装工艺对象stdout.write,它挂在全局对象。

(3)、出口和module.exports

在NodeJS,有两个结构域,其中分为全球范围和模块的范围。

复制代码代码如下所示:

变量名= 'var-name;

名称= 'name';

名称= 'global-name全球;

this.name = 'module-name;

console.log(全球。名称);

console.log(这个名字);

console.log(名称);



我们看到变量名= 'var-name;名称= 'name';定义的局部变量;

和全球。名称= 'global-name;是定义一个全局对象的名称属性,

this.name = 'module-name';一个模块对象的名称属性的定义

所以让我们验证,保存后test2.js,跑

复制代码代码如下所示:

VaR T1 =需要('。 / test1);

console.log(T1。名称);

console.log(全球。名称);



你可以看到,我们已经成功地引进了test1模块和运行测试代码,因为global.name输出test2。

和t1.name定义在测试模块通过this.name,表明这种分模块的范围对象。

出口和module.exports差别不大

module.exports是真正的界面,和出口的只是它的一个辅助工具,电话的收益而不是出口module.exports。

所有的方法和属性的出口收集分配给module.exports.of当然有一个前提,module.exports本身没有任何属性和方法。

如果Module.exports和方法的一些性质,收集出口的信息将被忽略。

栗子:

建立一个新文件bb.js

复制代码代码如下所示:

exports.name =函数(){

console.log(我的名字是大熊!);

};



创建一个测试文件test.js

U3000 U3000

复制代码代码如下所示:

var(=);

(BB的名字); / /我的名字是熊!



bb.js如下修改:

复制代码代码如下所示:

module.exports = 'bigbear!;

exports.name =函数(){

console.log(我的名字是大熊!);

};



引用bb.js执行一遍

复制代码代码如下所示:

var(=);

Bb.name(已经); / /不method'name



因此,您的模块不一定必须返回实例化的对象。您的模块可以是任何合法的Javascript对象——布尔值、数字、日期、JSON、字符串、函数、数组等。

(4),setTimeout、setInterval,process.nexttick,setimmediate

以下表单以摘要的形式出现

NodeJS的特点是事件驱动的,高并发的异步I / O,该发动机的特点是事件循环,事件聚集要安排相应的事件查看器,如闲置的观测器,定时观察,我 / O观察等等,每个事件的回路称为蜱,与从事件查看器事件处理的顺序,按照每个刻度。

调用setTimeout和setInterval()()时创建的定时器将被放置在红黑树的观察者,在每一次,将检查定时器的定时时间从红黑树,超过的话,立即实施相应的the.settimeout回调函数setInterval()和()的使用通过定时器。它们之间的区别在于后者是反复触发的。此外,由于时间设置太短,它会在第一次触发后触发触发器。

超时定时器触发,它将导致触发不准确,如setTimeout设置使用超时为5秒,当事件循环周期任务在第四秒,3秒的执行时间,然后setTimeout回调函数将在2秒过期,这是低精度的原因。这是更浪费,节省定时器采用红黑树和迭代的方式判断触发。

所有的回调函数的process.nexttick()将被放置在一个数组中,它们都将成为下一个滴答后立即执行。此操作更轻,时间准确。

该setimmediate回调函数()设置也在下一个滴答,和之间的区别()process.nexttick是两点:

1,他们所属的观察员有不同的优先权。process.nexttick()属于闲置的观测器,setimmediate()属于检查观察,空闲的优先级>检查。

2、由setimmediate回调函数()被放置在一个链表,每次只执行一个回调在链表中。这是为了确保每次能快速执行。

二、总结

1,理解全球物体存在的意义

2,出口和module.exports差别不大

3,控制台的底部是什么(流程对象的高级别封装)

4,之间的差异process.nexttick setInterval和setTimeout,,setimmediate

5、在NodeJS的两个范围