1. 개방 분석
이전 장에서는 NodeJS에 대한 기본 이론적 지식을 배웠습니다. 이 이론적 지식을 이해하는 것이 중요합니다. 다음 장에서는 공식 문서에서 다양한 모듈을 점차적으로 배울 것입니다. 글쎄,이 기사의 주인공이 무대에 등장 할 때입니다. 글로벌
공식적인 정의를 살펴 보겠습니다.
글로벌 개체이 객체는 모든 모듈에서 사용할 수 있습니다. 이러한 객체 중 일부는 실제로 글로벌 범위가 아니라 모듈 범위에 있지 않습니다.
이 객체는 모든 모듈에서 사용할 수 있습니다. 실제로 일부 객체는 글로벌 범위 범위가 아니라 모듈 범위에 있습니다. 이들은 식별됩니다.
브라우저에서 최상위 범위는 글로벌 범위입니다. 즉, 글로벌 범위에있는 브라우저에서 var something 글로벌 변수를 정의 할 것입니다.
노드에서 이것은 다릅니다. 최상위 범위는 글로벌 범위가 아닙니다. var something 해당 모듈에 로컬로 표시됩니다.
나는 모든 사람이 글로벌 대상의 개념에 익숙하지 않아야한다고 생각합니다. 브라우저에서 가장 높은 레벨 범위는 글로벌 범위입니다. 즉, "var"를 사용하여 글로벌 범위의 변수를 정의하면이 변수는 글로벌 범위로 정의됩니다.
그러나 Nodejs에서는 다릅니다. 최고 수준의 범위는 글로벌 범위가 아닙니다. 모듈에서 변수는 "var"를 사용하여 정의 되며이 변수는이 모듈의 범위에만 있습니다.
nodejs에서는 모듈에 정의 된 변수, 함수 또는 메소드가 해당 모듈에서만 사용할 수 있지만 내보내기 개체를 사용하여 모듈 외부로 전달할 수 있습니다.
그러나 Node.js에는 여전히 전역 범위가 있습니다. 즉, 모듈의로드가 필요하지 않은 변수, 함수 또는 클래스를 정의 할 수 있습니다.
동시에, 일부 글로벌 방법과 글로벌 클래스 글로벌 객체는 미리 사전 정의되며, 이는 Nodejs의 글로벌 네임 스페이스입니다. 모든 글로벌 변수, 함수 또는 객체는 객체의 속성 값입니다.
REPL RUNGING 환경에서 다음은 다음 문장을 통해 글로벌 객체의 세부 사항을 관찰 할 수 있습니다. 아래 그림을 참조하십시오.
전역 객체에 장착 된 관련 속성 값 객체에 대해 아래에서 하나씩 이야기하겠습니다.
(1), 과정
프로세스 {object} 프로세스 개체. 프로세스 객체 섹션을 참조하십시오.
프로세스 {object} 프로세스 객체입니다. 다음 장에서는 자세히 설명하겠습니다. 그러나 여기서는 먼저 API를 꺼내서 그것에 대해 이야기 할 것입니다.
process.nexttick (콜백)
이벤트 루프 주변의 다음 루프 에서이 콜백을 호출하십시오. 이것은 settimeout (fn, 0)에 대한 간단한 별칭이 아니며 훨씬 더 효율적입니다. 일반적으로 다른 I/O 이벤트가 발사되기 전에 실행되지만 몇 가지 예외가 있습니다. 아래의 process.maxtickdepth를 참조하십시오.
이벤트 루프의 다음 루프에서 콜백 콜백 기능. 이것은 훨씬 더 효율적이기 때문에 settimeout (fn, 0) 함수에 대한 간단한 별칭이 아닙니다.
이 기능은 I/O 전에 콜백 함수를 호출 할 수 있습니다. 객체 생성 후 및 I/O 작동이 발생하기 전에 특정 작업을 수행하려면이 기능이 매우 중요합니다.
많은 사람들이 node.js의 프로세스 사용법을 이해하지 못합니다. 프로세스 .nexttick ()이 어떤 프로세스인지, 사용 방법을 살펴 보겠습니다.
node.js는 단일 스레드입니다. 시스템 IO를 제외하고는 이벤트 폴링 프로세스 중에 동시에 하나의 이벤트 만 처리됩니다. 이벤트 폴링을 큰 대기열로 생각할 수 있습니다. 각 시점에서 시스템은 하나의 이벤트 만 처리합니다.
컴퓨터에 여러 CPU 코어가 있더라도 동시에 여러 이벤트를 병렬로 처리 할 수 없습니다. 그러나이 기능은 Node.js가 I/O 응용 프로그램을 처리하는 데 적합하지만 CPU 컴퓨팅 응용 프로그램에는 적합하지 않습니다.
각 I/O 응용 프로그램에서 각 입력 및 출력에 대한 콜백 기능 만 정의하면 이벤트 폴링 처리 큐에 자동으로 추가됩니다.
I/O 작업이 완료되면이 콜백 기능이 트리거됩니다. 그런 다음 시스템은 다른 요청을 계속 처리합니다.
이 프로세싱 모드에서 process.nexttick ()은 조치를 정의하고 다음 이벤트가 설문 조사 시점 에서이 조치를 실행하도록하는 것을 의미합니다. 예를 살펴 보겠습니다. 예에서는 다음 시점에서 호출하려는 foo ()가 있습니다.
코드 사본은 다음과 같습니다.
함수 foo () {
Console.error ( 'foo');
}
process.nexttick (foo);
Console.error ( 'bar');
위의 코드를 실행하면 "Bar"의 출력이 "Foo"앞에 있음을 알 수 있습니다. 이것은 foo ()가 다음 시점에서 실행되는 위의 진술을 확인합니다.
코드 사본은 다음과 같습니다.
술집
foo
settimeout () 함수를 사용하여 동일한 실행 효과를 달성 할 수 있습니다.
코드 사본은 다음과 같습니다.
settimeout (foo, 0);
Console.log ( 'bar');
그러나 내부 처리 메커니즘 측면에서 프로세스 .nextTick () 및 Settimeout (fn, 0)은 다릅니다. process.nexttick ()은 간단한 지연이 아니며 더 많은 기능이 있습니다.
보다 정확하게는 process.nexttick ()에 의해 정의 된 호출이 새 보본을 만듭니다. 현재 스택에서는 원하는만큼 많은 작업을 수행 할 수 있습니다. 그러나 Netxtick이 호출되면 기능은 부모 스택으로 반환해야합니다. 그런 다음 이벤트 폴링 메커니즘은 새로운 이벤트가 다시 처리 될 때까지 기다립니다. NextTick이 발견되면 새 스택이 생성됩니다.
프로세스를 사용할 상황을 살펴 보겠습니다 .nextTick () :
여러 이벤트에서 CPU 교차 집중 작업 집약적 작업 :
다음 예에는 compute ()가 있습니다. 우리는이 기능이 일부 운영 집약적 작업을 수행하기 위해 가능한 한 지속적으로 실행되기를 바랍니다.
그러나 동시에, 우리는 또한 시스템 이이 기능에 의해 차단되지 않으며 다른 이벤트에 응답하고 처리 할 수 있기를 바랍니다. 이 응용 프로그램 패턴은 단일 스레드 웹 서비스 서버와 같습니다. 여기서 우리는 process.nexttick ()을 사용하여 compute ()과 일반 이벤트 응답을 교차 집행 할 수 있습니다.
코드 사본은 다음과 같습니다.
var http = 요구 ( 'http');
function compute () {
// 복잡한 계산을 지속적으로 수행합니다
// ...
process.nexttick (compute);
}
http.createserver (function (req, res) {
res.writehead (200, { 'content-type': 'text/plain'});
Res.end ( 'Hello World');
}). 듣기 (5000, '127.0.0.1');
compute ();
이 모드에서는 Compute ()를 재귀 적으로 호출 할 필요가 없습니다. 이벤트 루프의 다음 시점에서 Compute ()를 정의하기 위해 Process.nextTick () 만 사용하면됩니다.
이 과정에서 새 HTTP 요청이 들어 오면 이벤트 루프 메커니즘이 먼저 새 요청을 처리 한 다음 Compute ()를 호출합니다.
반대로, Compute ()를 재귀 호출에 넣으면 시스템이 compute ()에서 차단되며 새로운 HTTP 요청을 처리 할 수 없습니다. 직접 시도해 볼 수 있습니다.
물론 CPU의 세그먼트에서 실행되는 동일한 응용 프로그램을 시뮬레이션하는 것입니다.
(2), 콘솔
Console {Object}는 stdout 및 stderr에 인쇄하는 데 사용되었습니다. Stdio 섹션을 참조하십시오.
콘솔 {object}는 표준 출력 및 오류 출력으로 인쇄하는 데 사용됩니다. 다음 테스트를 참조하십시오.
코드 사본은 다음과 같습니다.
Console.log ( "Hello Bigbear!");
for (콘솔의 var i) {
console.log (i+""+콘솔 [i]);
}
다음 출력 결과가 얻을 것입니다.
코드 사본은 다음과 같습니다.
var log = function () {
process.stdout.write (format.apply (this, arguments) + '/n');
}
var info = function () {
process.stdout.write (format.apply (this, arguments) + '/n');
}
var warn = function () {
writeError (format.apply (this, arguments) + '/n');
}
var error = function () {
writeError (format.apply (this, arguments) + '/n');
}
var dir = function (Object) {
var util = 요구 ( 'util');
process.stdout.write (util.inspect (Object) + '/n');
}
var time = function (label) {
times [label] = date.now ();
}
var timeend = function (label) {
var duration = date.now () - 시간 [레이블];
Exports.log ( 'undefined : nanms', 레이블, 지속 시간);
}
var trace = function (label) {
// TODO는 아마도 V8의 디버그 객체로 더 잘할 수 있습니다.
// 노출된.
var err = 새로운 오류;
err.name = '추적';
err.message = label || '';;
error.capturestacktrace (err, arguments.callee);
Console.error (err.stack);
}
var assert = function (expression) {
if (! expression) {
var arr = array.prototype.slice.call (인수, 1);
필요 ( 'assert'). Ok (false, format.Apply (this, arr));
}
}
이러한 기능을 통해 기본적으로 NodeJS가 글로벌 범위에 추가 한 내용을 알고 있습니다. 실제로, 콘솔 객체의 관련 API는 프로세스 객체에서 "stdout.write"만 캡슐화하고 글로벌 오브젝트에 매달려 있습니다.
(3), 수출 및 모듈
Nodejs에는 글로벌 범위와 모듈 범위로 나뉘어져있는 두 개의 스코프가 있습니다.
코드 사본은 다음과 같습니다.
var name = 'var-name';
이름 = '이름';
Global.name = 'Global-Name';
this.name = 'module-name';
Console.log (Global.name);
Console.log (this.name);
Console.log (이름);
var name = 'var-name'; name = 'name'; 정의 된 로컬 변수입니다.
Global.name = 'Global-Name'; 글로벌 오브젝트의 이름 속성을 정의합니다.
그리고 this.name = 'module-name'; 모듈 객체의 이름 속성을 정의합니다
그러니 확인하고 다음을 test2.js로 저장하고 실행합시다.
코드 사본은 다음과 같습니다.
var t1 = 요구 사항 ( './ test1');
Console.log (t1.name);
Console.log (Global.name);
결과에서 볼 수 있듯이 Test1 모듈을 성공적으로 가져오고 Global.name이 Test2에서 출력되므로 Test1 코드를 실행했습니다.
T1.Name은 TEST1 모듈에 this.Name을 통해 정의되어 있으며, 이는 모듈 스코프 오브젝트를 가리 킵니다.
수출과 모듈의 약간의 차이
Module.exports 는 실제 인터페이스이며 내보내기는 보조 도구 일뿐입니다. 통화로의 최종 반환은 내보내기 대신 Module.exports 입니다.
내보내기에 의해 수집 된 모든 속성 및 메소드는 Module.exports 에 할당됩니다. 물론, 이에 대한 전제 조건이 있습니다. 즉, Module.exports本身不具备任何属性和方法。
Module.exports 이미 일부 속성과 방법이있는如果,已经具备一些属性和方法,那么exports收集来的信息将被忽略。
밤나무를 가져 가십시오 :
새 파일 BB.JS를 만듭니다
코드 사본은 다음과 같습니다.
Exports.name = function () {
Console.log ( '내 이름은 Big Bear!');
};
테스트 파일 테스트를 만듭니다 .JS
코드 사본은 다음과 같습니다.
var bb = 요구 사항 ( './ bb.js');
bb.name (); // '제 이름은 Big Bear입니다! '
다음과 같이 BB.JS를 수정하십시오.
코드 사본은 다음과 같습니다.
module.exports = 'bigbear!' ;
Exports.name = function () {
Console.log ( '내 이름은 Big Bear!');
};
BB.JS를 다시 실행하는 것을 참조하십시오
코드 사본은 다음과 같습니다.
var bb = 요구 사항 ( './ bb.js');
bb.name (); // 방법 '이름'이 없습니다.
이것으로부터 우리는 당신의 모듈이 반드시 "설립 된 객체"를 반환 할 필요는 없음을 알 수 있습니다. 모듈은 법적 JavaScript 오브젝트 (Boolean, 번호, 날짜, JSON, 문자열, 함수, 배열 등) 일 수 있습니다.
(4), settimeout, setInterval, process.nexttick, setimmediate
다음은 요약의 형태입니다
Nodejs는 비동기 I/O에 의해 생성 된 이벤트 중심의 높은 동시성을 특징으로합니다. 이 기능을 생성하는 엔진은 이벤트 루프입니다. 이벤트는 유휴 관찰자, 타이머 관찰자, I/O 관찰자 등과 같은 해당 이벤트 관찰자로 분류됩니다. 이벤트 루프의 각 루프를 진드기라고합니다. 각 진드기는 처리를 위해 이벤트 관찰자에서 이벤트를 차지합니다.
settimeout () 또는 setinterval ()을 호출 할 때 생성 된 타이머는 타이머 관찰자 내부의 빨간색과 검은 색 트리에 배치됩니다. 틱 할 때마다 타이머가 빨간색과 검은 색 트리에서 타이밍 시간을 초과했는지 확인합니다. 타이밍을 초과하면 해당 콜백 함수가 즉시 실행됩니다. settimeout () 및 setinterval ()은 둘 다 타이머에서 사용됩니다. 차이점은 후자가 반복적으로 트리거되고 시간 설정이 너무 짧기 때문에 이전 트리거가 완료된 직후에 이전 트리거의 처리가 트리거됩니다.
타이머는 타임 아웃 트리거이므로 트리거 정확도가 줄어 듭니다. 예를 들어 Settimeout으로 설정된 시간 초과 시간은 5 초입니다. 이벤트 루프가 4 초에 작업을 통해 실행되고 실행 시간이 3 초인 Settimeout 콜백 함수가 2 초 동안 만료되므로 정확도가 감소하는 이유입니다. 그리고 타이머와 판단 트리거는 빨간색과 검은 색 나무와 반복적 인 방법을 사용하여 저장되기 때문에 성능 낭비입니다.
process.nexttick ()을 사용하여 설정 한 모든 콜백 함수는 배열에 배치되며 다음에 진드 할 때 즉시 실행됩니다. 이 작업은 가볍고 정확도가 높습니다.
setimmediate ()에 의해 설정된 콜백 함수도 다음 진드기에서 호출됩니다. 그것과 process.nexttick ()의 차이는 두 가지 요점입니다.
1. 그들이 속한 관찰자의 실행 우선 순위는 다릅니다. process.nexttick ()는 유휴 관찰자에 속하며 setimmediate ()는 체크 관찰자에 속하며 유휴의 우선 순위> 점검입니다.
2. setimmediate ()에 의해 설정된 콜백 함수는 링크 된 목록에 배치되며 링크 된 목록의 콜백은 매번 실행됩니다. 이것은 모든 진드기를 빠르게 실행할 수 있도록하기위한 것입니다.
둘째, 요약합시다
1. 글로벌 대상의 존재의 의미를 이해
2. 수출과 모듈의 약간의 차이
3. Console Build의 기본 레이어는 무엇입니까 (프로세스 개체의 고급 캡슐화)
4. settimeout, setInterval, process.nexttick, setimmediate의 차이
5. Nodejs의 두 범위