1. Вступительный анализ
В предыдущей главе мы узнали основное теоретическое знание Nodejs. Понимание этого теоретического знания имеет решающее значение. В последующих главах мы постепенно изучаем различные модули в официальных документах. Ну, настало время, чтобы главный герой этой статьи появился на сцене. Глобальный
Давайте посмотрим на официальное определение:
Глобальные объекты Эти объекты доступны во всех модулях. Некоторые из этих объектов на самом деле не в глобальном масштабе, но в сфере модуля - это будет отмечено.
Эти объекты доступны во всех модулях. На самом деле, некоторые объекты не входят в глобальную масштаб, а в объеме модуля - они будут идентифицированы.
В браузерах масштаб высшего уровня является глобальным масштабом. Это означает, что в браузерах, если вы находитесь в глобальном масштабе var something определит глобальную переменную.
В узле это другое. Охват верхнего уровня не является глобальной областью; var something внутри модуля узла будет локальным для этого модуля.
Я думаю, что каждый не должен быть незнаком с концепцией глобальных объектов. В браузере наиболее высоким объемом уровня является глобальная область, что означает, что если вы используете «var» для определения переменной в глобальной области, эта переменная будет определена как глобальная область.
Но это отличается в Nodejs. Самый высокий уровень масштабов не является глобальным масштабом. В модуле переменная определяется с использованием «var», и эта переменная находится только в объеме этого модуля.
В Nodejs, переменные, функции или методы, определенные в модуле, доступны только в этом модуле, но могут быть переданы вне модуля с помощью объекта Exports.
Однако в Node.js все еще есть глобальная область, то есть вы можете определить переменные, функции или классы, которые не требуют загрузки каких -либо модулей.
В то же время некоторые глобальные методы и глобальные глобальные объекты класса заранее заранее, которые являются глобальными пространствами имен в Nodejs. Любые глобальные переменные, функции или объекты являются значениями атрибута объекта.
В среде, управляемой Repl, вы можете наблюдать детали в глобальном объекте через следующее утверждение, см. Рисунок ниже:
Я расскажу о соответствующих объектах значения атрибута, установленных на глобальном объекте один за другим ниже.
(1), процесс
Process {Object} Объект процесса. См. Раздел объекта процесса.
Процесс {объект} Это объект процесса. Я подробно объясню в последующих главах, но здесь я сначала возьму API, чтобы поговорить об этом.
process.nexttick (обратный вызов)
На следующем цикле вокруг цикла события позвоните в этот обратный вызов. Это не простой псевдоним для Settimeout (FN, 0), это гораздо более эффективно. Обычно он работает перед любыми другими событиями ввода -вывода, но есть некоторые исключения. См. Process.maxtickdepth ниже.
Функция обратного вызова обратного вызова в следующем цикле цикла событий. Это не простой псевдоним для функции SetTimeout (FN, 0), потому что она гораздо более эффективна.
Эта функция может вызвать нашу функцию обратного вызова перед любой ввод -выводом. Если вы хотите выполнить определенные операции после создания объекта и до начала работы ввода/вывода, эта функция очень важна для вас.
Многие люди не понимают использования процесса.nexttick () в node.js. Давайте посмотрим, что такое процесс.nexttick () и как его использовать.
Node.js однопоточный. За исключением системы IO, только одно событие будет обработано одновременно в процессе его опроса. Вы можете думать о опросе событий как о большой очереди, в каждом моменте система будет обрабатывать только одно событие.
Даже если на вашем компьютере есть несколько ядер ЦП, вы не можете обрабатывать несколько событий параллельно одновременно. Но эта функция делает Node.js подходящим для обработки приложений ввода -вывода, но не для вычислительных приложений ЦП.
В каждом приложении ввода/вывода вам нужно только определить функцию обратного вызова для каждого ввода и вывода, и они будут автоматически добавлены в очередь обработки опросов событий.
Когда операция ввода/вывода будет завершена, эта функция обратного вызова будет запускается. Затем система продолжит обрабатывать другие запросы.
В этом режиме обработки процесс. Давайте посмотрим на пример. В примере есть foo (), который вы хотите позвонить на следующий момент времени, вы можете сделать это:
Кода -копия выглядит следующим образом:
функция foo () {
console.error ('foo');
}
process.nexttick (foo);
console.error ('bar');
Запустите приведенный выше код, и вы увидите, что вывод «Бар» находится перед «Foo». Это проверяет приведенное выше утверждение, которое Foo () работает в следующем моменте.
Кода -копия выглядит следующим образом:
бар
Фу
Вы также можете использовать функцию settimeout () для достижения того же эффекта выполнения:
Кода -копия выглядит следующим образом:
setTimeout (foo, 0);
console.log ('bar');
Однако с точки зрения механизма внутренней обработки, процесс. Process.nexttick () не является простой задержкой, он имеет больше функций.
Точнее, вызов, определенный Process.NextTick (), создает новый SUPACK. В текущем стеке вы можете выполнить столько операций, сколько захотите. Но как только Netxtick вызывается, функция должна быть возвращена в родительский стек. Затем механизм опроса событий ждет, пока новые события будут обработаны снова. Если найден Nexttick, будет создан новый стек.
Давайте посмотрим, какие обстоятельства использовать Process.nexttick ():
Задачи на перекрестную эксплуатацию задач по интенсивному процессору в нескольких соревнованиях:
В следующем примере есть Compute (). Мы надеемся, что эта функция будет выполняться как можно более непрерывным для выполнения некоторых задач с интенсивными операциями.
Но в то же время мы также надеемся, что система не будет заблокирована этой функцией, а также сможет отвечать и обрабатывать другие события. Этот шаблон приложения похож на один поточный сервер веб -служб. Здесь мы можем использовать процесс.
Кода -копия выглядит следующим образом:
var http = require ('http');
функция 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 ();
В этом режиме нам не нужно рекурсивно вызывать (). Нам нужно только использовать процесс.
Во время этого процесса, если появится новый HTTP -запрос, механизм цикла событий сначала обработает новый запрос, а затем Call Compute ().
Напротив, если вы поместите Compute () в рекурсивный вызов, система будет заблокирована в Compute () и не может обрабатывать новые HTTP -запросы. Вы можете попробовать сами.
Конечно, мы не можем получить реальные преимущества параллельного выполнения в рамках нескольких процессоров через процесс.
(2), Консоль
Консоль {Object} используется для печати в STDOUT и Stderr.SE в разделе Stdio.
Консоль {Object} используется для печати на стандартный вывод и вывод ошибок. См. Следующий тест:
Кода -копия выглядит следующим образом:
console.log ("Привет, Большой Магист!");
для (var i в консоли) {
console.log (i+""+console [i]);
}
Будут получены следующие результаты выходных данных:
Кода -копия выглядит следующим образом:
var log = function () {
process.stdout.write (format.apply (this, аргументы) + '/n');
}
var info = function () {
process.stdout.write (format.apply (this, аргументы) + '/n');
}
var warn = function () {
writeerror (format.apply (this, аргументы) + '/n');
}
var error = function () {
writeerror (format.apply (this, аргументы) + '/n');
}
var dir = function (object) {
var util = require ('util');
process.stdout.write (util.inspect (object) + '/n');
}
var time = function (метка) {
times [label] = date.now ();
}
var timeend = function (метка) {
var duration = date.now () - times [label];
exports.log ('undefined: nanms', метка, продолжительность);
}
var trace = function (метка) {
// Тодо, вероятно, может сделать это лучше с объектом отладки V8, как только это
// незащищенный.
var err = новая ошибка;
err.name = 'trace';
err.message = метка || '';
Error.capturestacktrace (err, arguments.callee);
console.error (err.stack);
}
var assert = function (выражение) {
if (! Выражение) {
var arr = array.prototype.slice.call (аргументы, 1);
require ('assert'). OK (false, format.apply (this, arr));
}
}
Благодаря этим функциям мы в основном знаем, что Nodejs добавила к глобальному объему. Фактически, соответствующие API на консольном объекте только инкапсулируют «stdout.write» на объект процесса и повесят его на глобальном объекте.
(3), экспорт и модуль.exports
В Nodejs есть две области, разделенные на глобальную область и объем модуля
Кода -копия выглядит следующим образом:
var name = 'var-name';
name = '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 = require ('./ test1');
console.log (t1.name);
console.log (global.name);
Как видно из результатов, мы успешно импортировали модуль Test1 и запустили код test1, потому что Global.Name выводится в Test2.
T1.name определяется в модуле Test1 через это.
Небольшая разница между экспортом и модулем.
Module.exports - это настоящий интерфейс, а экспорт - это всего лишь вспомогательный инструмент для него. Окончательным возвратом к вызову является Module.exports вместо экспорта.
Все свойства и методы, собранные экспортом, присваиваются Module.exports . Конечно, существует предпосылка для этого, то 。 Module.exports本身不具备任何属性和方法
如果, Module.exports已经具备一些属性和方法,那么exports收集来的信息将被忽略。
Возьмите каштан:
Создайте новый файл bb.js
Кода -копия выглядит следующим образом:
exports.name = function () {
console.log («Меня зовут Big Bear!»);
};
Создайте тестовый файл test.js
Кода -копия выглядит следующим образом:
var bb = require ('./ bb.js');
bb.name (); // 'Меня зовут Big Bear! '
Изменить BB.JS следующим образом:
Кода -копия выглядит следующим образом:
module.exports = 'bigbear!' ;
exports.name = function () {
console.log («Меня зовут Big Bear!»);
};
Обратитесь к выполнению BB.JS снова
Кода -копия выглядит следующим образом:
var bb = require ('./ bb.js');
bb.name (); // не имеет метода «Имя»
Из этого мы видим, что ваш модуль не обязательно должен возвращать «институт объекта». Ваш модуль может быть любым юридическим объектом JavaScript -Boolean, Number, Date, JSON, строка, функция, массив и т. Д.
(4), setTimeout, setInterval, process.nexttick, setimmediate
Следующее в форме резюме
Nodejs характеризуется управляемой событиями, высокой параллельностью, генерируемой асинхронным вводом-выводом. Двигатель, который производит эту функцию, является цикла событий. События классифицируются на соответствующие наблюдатели событий, такие как простоя наблюдатели, наблюдатели таймера, наблюдатели ввода -вывода и т. Д. Каждый цикл цикла событий называется клером. Каждый тик выводит события из наблюдений за событиями в последовательности для обработки.
Таймер, созданный при вызове settimeout () или setInterval (), будет помещен в красное и черное дерево внутри наблюдателя таймера. Каждый раз, когда вы отмечаете, он проверяет, превышал ли таймер время времени от красного и черного дерева. Если он превышает время, соответствующая функция обратного вызова будет выполнена немедленно. setTimeout () и setInterval () оба используются таймерами. Разница состоит в том, что последнее запускается неоднократно, и поскольку настройка времени слишком короткая, обработка после предыдущего триггера будет вызвана сразу после завершения предыдущего триггера.
Поскольку таймер является триггером тайм -аута, это снизит точность триггера. Например, время ожидания, установленное с SetTimeout, составляет 5 секунд. Когда цикл событий выполняется через задачу в 4 -й секунде, а время выполнения составляет 3 секунды, функция обратного вызова Settimeout истекает в течение 2 секунд, что является причиной снижения точности. И поскольку триггеры таймера и суждения сохраняются с использованием красных и черных деревьев и итеративных методов, это пустая трата производительности.
Все функции обратного вызова, установленные с использованием process.nexttick (), будут размещены в массиве, и все будут выполнены немедленно в следующий раз, когда вы отмечаете. Эта операция легкая и имеет высокую точность времени.
Функция обратного вызова, установленная на setimmediate (), также вызывает на следующем тике. Разница между ним и процессом.nexttick () составляет две точки:
1. Приоритет исполнения наблюдателя, к которому они принадлежат, отличается. Process.nexttick () принадлежит к простоям наблюдателю, setimmediate () принадлежит контрольному наблюдателю, а приоритет холостого хода> Проверка.
2. Функция обратного вызова, установленная SetImmediate (), помещается в связанный список, и только один обратный вызов в связанном списке выполняется каждый раз. Это должно обеспечить, чтобы каждый тик был быстро выполнен.
Во -вторых, давайте обобщу
1. Понять смысл существования глобальных объектов
2. Небольшая разница между экспортом и модулем.
3. Каков основной слой консоли (высокоуровневая инкапсуляция объектов процесса)
4. Разница между SetTimeout, SetInterval, Process.Nexttick, SetImmediate
5. Две области в Nodejs