Front-end macho познакомит вас с серией Nodejs (1)

Node.js
Front-end macho познакомит вас с серией Nodejs (1)

1. Введение в Nodejs

В начале развития фронтенд-технологий фронтенд-инженеры могли использовать только html, css и javascript для интерактивной разработки страниц, но с появлением Nodejs, сломалсяjavascriptСитуация, которую можно запустить только в браузере, реализует унификацию интерфейсной и внутренней сред программирования. Ниже приводится краткое введение в характеристики Nodejs:

1. Окружающая среда выполнения JavaScript на основе двигателя Chrome V8

commonjsа такжеAMDЭти два модуля, которыеcommonjsсерверная частьjs(Nodejs)模块化的规范。 то естьNodejsJS

Ryan DahlC++развивающийся.Nodeиспользование в окружающей средеjavascriptязык, чтобы фронтенд-инженеры имели более широкое пространство для разработки, подобноеReact/VuejsФреймворк разработки такого фронтенд-фреймворка становится очень мощным и ответственным.

2, драйвер события

Так называемая событийная стратегия относится к стратегии принятия решений в процессе непрерывного управления транзакциями, то есть слежения за событиями, происходящими в текущий момент времени, мобилизации доступных ресурсов и выполнения связанных задач, чтобы возникающие проблемы могут быть решены, а транзакции не накапливаются.

Ниже приведена аналогия для имитации драйвера событий NodeJS: Предположим, что сейчас мы в Макдональдсе, обычная операция такова: закажите оплату на соответствующий номер, затем дождитесь номера на месте, подождите, пока еда будет готова, клерк позвонит по номеру, мы получили ваши собственные блюда. обработка - есть.

event queueCallback), можно использовать в мероприятиях (кулинария,I/O) и продолжить выполнение следующей логики (есть) после завершения обработки. 

1.png

(1)NodeЭто однопоточный язык, использующий управляемый событиями и асинхронный механизм обратного вызова. При выполнении кода основной поток выполняется последовательно сверху вниз, когда есть место, которое нужно перезвонить, оно будет добавлено в очередь событий, а затем основной поток продолжит спускаться вниз, и не будет выполнить событие до конца операции.обратный вызов в очереди

(2)NodeКогда очередь событий для выполнения события, если вы сталкиваетесь с обратным вызовом, по-прежнему находится в порядке, который вы добавляете в очередь событий, добавляется выполнение основного потока после обнаружения обратного вызова, пока он не будет завершен.

(3)NodeПроцесс создает цикл, каждый цикл является циклом, просмотра в очереди события, чтобы увидеть, необходимо ли обрабатывать событие, если есть для удаления события и выполнения связанных функций. Обработка блокирующего события используется для обеспечения работы работы, не занимая основной процесс цикла.

3. Неблокирующий ввод/вывод, один поток

I/0Это можно понимать как операцию чтения и записи на сервере, неблокирующуюI/OТакже известен как асинхронныйI/O, что, очевидно, соответствует блокирующему типуI/O.

Традиционные серверные языки в основном многопоточные, блокирующиеI/O. Это тожеNodeРазница в том, что в традиционных серверных языках при установлении соединения с пользователем каждое соединение представляет собой поток.

Когда подключено 100 000 пользователей, на сервере существует 100 000 потоков. блокировкаI/Oозначает, что когда поток выполняетсяI/O Во время работы этот поток будет блокироваться, ожидаяI/O Продолжить выполнение после завершения операции.

Рассмотрим бизнес-сценарий, в котором данные необходимо извлекать из нескольких источников данных, а затем обрабатывать. Если для получения профиля и операции временной шкалы требуется 1 с, то для его последовательного получения требуется 2 с.

а такжеNodejsМетод обработки: встречаI/OМероприятие создаст поток для выполнения, то основной нить выполнения будет продолжаться, следовательно, взятьprofileI/OtimelineI/OСобытие, два действия выполняются параллельно, если каждый требуется 1S, то общее время - 1 с.

2.png

Вверху, вNode.js, только один поток непрерывно опрашивает очередь на наличие событий. Для операций ввода-вывода, таких как файловые системы баз данных, включая HTTP-запросы и другие операции, которые легко заблокировать и ждать.

Если он также реализован в этом отдельном потоке, он обязательно заблокирует выполнение других рабочих задач, поэтомуJavascript/Node.js будет доверить основной пул резьбы (Thread Pool) для выполнения и сообщит пулу потоков функцию обратного вызова, чтобы один поток продолжал выполнять другие задачи. Когда эти блокирующие операции завершены, результаты помещаются в очередь вместе с предоставленной функцией обратного вызова. непрерывно считывает из события очереди, после чтения заблокированных результатов операции результаты операции будут использоваться в качестве входных параметров функции обратного вызова, а затем функция обратного вызова будет активирована и запущена.

осторожность,Node.jsЭтот единственный поток отвечает не только за чтение событий из очереди, но также выполняет текущую функцию обратного вызова, что является основной особенностью, отличающей его от многопоточного режима.В многопоточном режиме один поток отвечает только за чтение событий из очереди. и не делает ничего другого, делегирует другим потокам выполнение других задач, особенно в случае многоядерного,CPUЯдро отвечает за чтение событий очереди,CPUЯдро отвечает за выполнение активной задачи, что лучше всего подходит для задач, интенсивно использующих ЦП.

по очереди,Node.jsЗадача активации выполнения, то есть задача в функции обратного вызова, по-прежнему выполняется в одном потоке, отвечающем за опрос, которому суждено быть неспособным выполнять ресурсоемкие задачи, такие как преобразование JSON в другие форматы данных и т. д. Эти задачи повлияют на эффективность запроса колеса событий.

2. Отладка узлов

Если вы хотите делать что-то хорошо, вы должны сначала отточить свои инструменты.Отладка во фронтенд-разработке — очень важная часть, которая может помочь нам лучше находить ошибки и исправлять их. Ниже приводится введение в метод отладки Node (в среде Windows другие среды пока не будут расширены):

1. Имя файла узла + console.log

Введите имя файла Node + js в командной строке, чтобы выполнить файл js сверху вниз,NodeВ грамматике тоже естьconsoleСвязанныйapiТаким образом, мы можем объединить два в консоли для ввода желаемых данных:

3.png

Версия Node6.3 + предоставляет два протокола для отладки: протокол отладчика v8 и протокол инспектора v8 могут использовать (v8) запуск стороннего клиента / IDE и других узлов мониторинга и вмешательства для отладки.

v8 Inspector Protocol — это недавно добавленный протокол отладки, который взаимодействует с клиентом/IDE через веб-сокет (обычно через порт 9229) и предоставляет графический интерфейс отладки на основе инструментов разработчика браузера Chrome/Chromium. Ниже приведены официальные инструкции по отладке:

4.png

Тот же код, что и выше:

// index.js

var fs = require("fs");

fs.readFile('./txt/remove.txt', function(err, data) {
  if(err) throw err;
  console.log('txt 文件数据:\n', data.toString());
})

fs.readFile('./html/first-child.html', {encoding: 'utf-8'}, (err, data) => {
  if(err) throw err;
  console.log('html 数据:\n', data);
})

(1) Выполните --inspect связанные команды в командной строке cmd

5.png

ВышеупомянутыйNode --inspectна основеChrome/ChromiumбраузерdevtoolsОбеспечивает графический сектор отладки, на этот раз мы вводим localhost: 9229 для доступа к странице не найдена, это потому, что--inspectДля общей программы она мигает, и выполнение завершается до отправки сигнала точки останова. Точки останова вообще не работают, это время можно использовать--inspect-brk, что означает, что точка останова останавливается до выполнения кода.

6.png

На этот раз мы посещаемlocalhost:9229Вы можете видеть, что на странице отображается «ожидался запрос webSockets», откройте панель отладки, вы можете увидетьelementsРядом с ним есть зеленый значок узла, нажмите для отладки, метод отладки такой же, как мы обычно делаем вchromeОтладка в основном такая же.

7.png

8.png

(2) Выполнить --inspect соответствующие инструкции в vscode

vscodeвстроенныйNode debugger,служба поддержкиv8 Debugger Protocolа такжеv8 Inspector Protocol两种协议。 дляv8 Inspector Protocol,只需要在配置里添加一条 Attach 类型配置即可。 существуетDebugvscode/launch.json

9.png

Node --inspect index.jsНа панели VSCODE мы можем увидеть точки выкиды кода в том, что мы хотим, слева, есть переменные, наблюдение, стек вызовов, точек обрыва тем из нас, знакомых с панелью ввода в эксплуатацию, если вкладNode --inspect index.js, выполнение кода останавливается перед первой строкой, поэтомуvscodeОтладка также является более надежным методом отладки.

10.png

Три, Nodejs модуль FS

Согласно официальной документации, модуль fs можно использовать для взаимодействия с файловой системой (аналогично стандартным функциям POSIX). Все операции с файловой системой имеют синхронные формы, формы обратного вызова и обещания. Чтобы использовать этот модуль, вы должны импортировать:

const fs = require('fs');

Ниже представлены некоторые часто используемые методы fs api, а оставшиеся API можно найти и запросить на официальном сайте Nodejs:

1, флаг файловой системы

Прежде чем начать знакомство с модулем fs, позвольте мне представить флаги файловой системы fs, которые будут часто использоваться позже. Когда опция флага принимает строку, доступны следующие флаги:

'a':  打开文件用于追加。 如果文件不存在,则创建该文件。
'ax':  类似于 'a',但如果路径存在,则失败。
'as':  打开文件用于追加(在同步模式中)。 如果文件不存在,则创建该文件。
'as+':  打开文件用于读取和追加(在同步模式中)。 如果文件不存在,则创建该文件。
'r':  打开文件用于读取。 如果文件不存在,则会发生异常。
'r+':  打开文件用于读取和写入。 如果文件不存在,则会发生异常。
'rs+':  打开文件用于读取和写入(在同步模式中)。 指示操作系统绕过本地的文件系统缓存。
'w':  打开文件用于写入。 如果文件不存在则创建文件,如果文件存在则截断文件。
'wx':  类似于 'w',但如果路径存在,则失败。
'w+':  打开文件用于读取和写入。 如果文件不存在则创建文件,如果文件存在则截断文件。
'wx+':  类似于 'w+',但如果路径存在,则失败。

2. fs.readFile

readFile — одна из основных функций модуля fs, которая используется для чтения всего содержимого файла.Ниже приводится введение в официально предоставленные методы:

11.png

Разбираем его параметр за параметром:

(1) путь

Тип пути может бытьstring、Buffer、URЗемляinteger; Обычно мы заполняем относительный или абсолютный путь к файлу, соответствующему строковому типу.

fs.readFile('./txt/remove.txt', function(err, data) {
  if(err) throw err;
  console.log('txt 文件数据:\n', data.toString());
})

integerОтносится к дескриптору файла, а дескриптор файла относится к тому, что каждому открытому файлу назначается простой числовой идентификатор, называемый дескриптором файла.В fs файлом можно манипулировать в соответствии с дескриптором файла fd, мы можем пройти черезfs.openДавайте попробуем, результат выполнения кода такой же, как и выше:

// r 表示打开文件用于读取。 如果文件不存在,则会发生异常
fs.open('./txt/remove.txt', 'r', (err, fd) => {
  if(err) throw err;
  console.log(fd);  
  fs.readFile(fd, (err, data) => {
    console.log('通过文件描述符读取', data.toString());
  })
})
// 最终输出 fd 的值为一个整数

путь тоже может бытьBufferТипы,BufferОбъекты, используемые для представления последовательности байтов фиксированной длины,BufferклассJavaScriptизUint8Array

BufferдаNodeВажный тип, о нем будет подробно рассказано позже в отдельном, здесь не начинать.

// 执行结果与上面代码一致,只是把路径转为了 Buffer
const fileBuffer = Buffer.from('./txt/something.txt', 'utf-8');
fs.readFile(fileBuffer, { encoding: 'utf-8' }, (err, data) => {
  if(err) throw err;
  console.log(data);
})

Начиная с версии Node v7.6.0, в path добавлена ​​поддержка объектов URL. для большинстваfsфункция модуля,pathилиfilenameПараметры могут быть переданы вWHATWG URL объект.仅支持使用 file: 协议的 URL 对象.

Файловый протокол в основном используется для доступа к файлам на локальном компьютере, точно так же, как открытие файлов в проводнике Windows. Для использования протокола File основной формат выглядит следующим образом:file:///文件路径,比如要打开D盘images文件夹中的pic.gifфайл, может основываться на путиfile:///D:/images/pic.gifЗапрос.

// 根据想要访问的文件地址转换成 URL 对象
const fileURL = new URL('file:///C:/Users/james/Desktop/training/Node/txt/something.txt');
fs.readFile(fileURL, { encoding: 'utf-8' }, (err, data) => {
  if(err) throw err;
  console.log(data);
})

(2) варианты

optionsЕсть два основных параметра:encodingа такжеflag.encodingПредставляет формат кодировки прочитанного файла, если не указанencodinг, вернуть оригиналBuffer, его значения в основном:

type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";

flag относится к флагу файловой системы, подробности см. в части 1 этой главы.

(3) обратный вызов

callbackОтносится к функции обратного вызова после завершения чтения файла.Основных параметров два:errorтак же какdata,errorЗдесь не говорите данные в соответствии сencodingBuffer

promiseформа,readFileSyncдаreadFilereadFileТо же самое, он также возвращает прочитанные данные.

12.png

Синхронная форма будет блокироватьNode.jsЦикл событий и дальнейшее выполнение JavaScript до завершения операции.

let data = fs.readFileSync('./txt/something.txt', { encoding: 'utf-8' });
console.log('同步获得的数据为:', data);
// 由于同步阻塞的缘故,console 输出的 data 数据为 something.txt 文件内的数据

3. fs.writeFile

writeFileЭто одна из основных функций модуля FS и используется для записи данных в файлы. Ниже приведено введение в официально предоставленные методы:

13.png

Разбираем его параметр за параметром:

(1) путь

здесьpathа такжеreadFilleизpath

fs.writeFile(), сначала напишите строку'Hello'И затем напишите строку' World', файл будет содержать'Hello, World', и может содержать некоторые необработанные данные файла (в зависимости от размера исходного файла и расположения файлового дескриптора). Если вместо дескриптора используется имя файла, файл будет гарантированно содержать только', World'.

// writeFile 的 path 为字符串,在 flag 取默认值的情况,hello 完全替换之前的文本
fs.writeFile('./txt/copy.txt', 'hello', (err) => {
  if(err) throw err;
})

// writeFile 的 path 为文件描述符,在 flag 取默认值的情况,hello 以及,I am james 并没有完全替换之前的文本,而是包含了这两部分
fs.open('./txt/copy.txt', 'r+', (err, fd) => {
  fs.writeFile(fd, 'hello', (err) => { if(err) throw err });
  fs.writeFile(fd, ',I am james', (err) => { if(err) throw err });
})

(2) данные

dataТипы могут быть:string、Buffer、TypedArrray和DataView. В основном представлено здесьTypedArrray和DataView. отNodeизtsЗаявление может знать,TypedArrrayСуществуют в основном следующие типы, которыеJavascriptИндексируемые объекты коллекций в стандартных встроенных объектах, которые здесь не описаны:

 type TypedArray =
        | Uint8Array
        | Uint8ClampedArray
        | Uint16Array
        | Uint32Array
        | Int8Array
        | Int16Array
        | Int32Array
        | BigUint64Array
        | BigInt64Array
        | Float32Array
        | Float64Array;

14.png

DataViewЭто также стандартный встроенный объект Javascript. Это представление интерфейса низкого уровня, которое может читать и записывать несколько числовых типов из двоичных объектов ArrayBuffer. Ниже приведено содержание объявления машинописного текста:

interface DataViewConstructor {
    readonly prototype: DataView;
    new(buffer: ArrayBufferLike, byteOffset?: number, byteLength?: number): DataView;
}
declare var DataView: DataViewConstructor;

(3) варианты

writeFileЕсть три параметра: Опции:encoding、mode和flag

Unlink — одна из основных функций модуля fs.Метод unlink — это метод удаления файлов модулем fs.Ниже приводится официальное введение метода:

15.png

(1) путь

Всего три параметра пути: строка, буфер и URL, без файлового дескриптора.

(2) обратный вызов

В дополнение к возможным исключениям, никаких других запросов параметров завершается обратным вызовом.

(3) отключить синхронизацию

Unnenchsync - это синхронный метод записи, за исключением того, что нет функции обратного вызова, метод вызова записывает данные таким же образом, как WriteFile, но блокирует цикл событий Node.js и дополнительный JavaScript, пока операция не будет завершена.

5. фс.открыть

Метод open в основном используется для открытия файлов, но возвращаемые данные представляют собой файловый дескриптор, приведенный выше.readFileВведение путь упомянул. Анализ, а также одинаковые параметры Readfile Open Method.

16.png

6, разница между несколькими режимами чтения и записи

readFile,read, createReadStreamwriteFile,write, createWriteStreamТри метода. Давайте посмотрим на различия между ними:

(1) readfile и writefile

readFileМетод файла содержимого должен быть прочитан в полный буфер чтения, затем содержимое файла прочитано из буферной зоны; файл содержимого writeFile должен быть записан в полный буфер чтения, после чего буфер запишет содержимое файла. Здесь операции чтения и записи, содержимого документа в целом, однократное чтение содержимого файла в буферную зону, назначенную буферную область и, в течение этого периода,Node.jsНикакой другой обработки выполняться не будет. Поэтому при чтении и записи больших файлов область кэша может «взорваться».

(2) читать и писать

Метод чтения для чтения содержимого файла заключается в непрерывном чтении небольшого фрагмента содержимого файла в область буфера и, наконец, чтении содержимого файла из области буфера;

17.png

18.png

Давайте посмотрим на производительность через код:

// new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz

fs.open('./txt/new-file.txt', 'r', (err, fd) => {
  if(err) throw err;
  var buf = Buffer.alloc(225);
  fs.read(fd, buf, 0, 12, 6, (err, bytesRead, buffer) => {
    if(err) throw err;
    console.log(buf.slice(0, bytesRead).toString(), buffer.toString());
  })
})
// 汉字在 Buffer 里面占三个位置
console.log(Buffer.from('我看看占了多少位置', 'utf-8').length);

Результат:

19.png

Когда метод записи записывает содержимое, Node.js выполняет следующий процесс: 1. Записать данные для записи в буфер памяти; 2. После заполнения области буфера запишите содержимое области буфера в файл; 3. Повторяйте шаги 1 и 2, пока все данные не будут записаны в файл;

20.png

21.png

Давайте посмотрим на производительность через код:

// new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz 我是原有的内容

fs.open('./txt/new-file.txt', 'r+', (err, fd) => {
  if(err) throw err;
  var buf = Buffer.from('我是被写入的内容');
  fs.write(fd, buf, 0, 24, 26, (err, bytesWritten, buffer) => {
    if(err) throw err;
    console.log(buf.slice(0, bytesWritten).toString(), buffer.toString    ());
  })
})

// 执行完毕后,new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz 我是被写入的内容

Результат ввода следующий:

22.png

Для вышеописанных операций чтения и записи Node.js разделит файл на части и будет работать пошагово, позволяя выполнять другие операции в процессе чтения и записи файла, но иногда нас не волнует содержимое файла. весь файл, но сосредоточиться только на чтении из файла.Некоторые данные и обработка, которая должна быть выполнена при чтении данных, мы также можем использовать файловый поток (createReadStream и createWriteStream) для обработки

(3) createReadStream и createWriteStream

createReadStreamМетод создает объект ReadStream, который считывает содержимое файла в виде потоковых данных:

23.png

Давайте посмотрим на производительность через код:

// new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz 我是原有的内容

var readStream = fs.createReadStream('./txt/new-file.txt', { flags: 'r', encoding: 'utf-8', start: 0, end: 25 });

readStream.on('open',function(fd) {
  console.log('开始读取文件');
});

readStream.on('pause', function() {
  console.log('暂停读取文件');
})

readStream.on('data', function(data) {
  console.log('读取到数据:');
  console.log(data);
  readStream.pause();
});

setTimeout(() => {
  console.log('1s 后取消暂停');
  readStream.resume();
}, 1000)

Результат выглядит следующим образом:

24.png

The above methods can monitor the process of reading and writing files, and define related methods pause and resume to suspend or resume the file read operation, and can monitor whether the buffer data is full or all output when writing, and readStream monitor The events are следующим образом:

25.png

Метод createWriteStream создает объект WriteStream, который записывает потоковые данные в файл:

26.png

Давайте посмотрим на производительность через код:

// new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz 我是原有的内容

var writeStream = fs.createWriteStream('./txt/new-file.txt', { flags: 'r+', encoding: 'utf-8', start: 26 });

writeStream.on('finish', () => {
  console.log('写入结束')
})

var words = Buffer.from('我是写入的内容');

writeStream.write(words, (err) => {
  if(err) throw err;
  writeStream.emit('finish');
});

// 执行完毕后,new-file.txt 的文本内容:abcdefghijklmnopqrstuvwxyz 我是写入的内容

writeStreamВы можете следить за событиями:

27.png