Расскажите об общих концепциях в Node.

Node.js внешний интерфейс

В процессе изучения Node нам необходимо понять некоторые основные понятия. Что такое Node и какие проблемы он решает, а также характеристики Node. Включая тупо неразличимые процессы и потоки, синхронизацию и асинхронность, блокировку и неблокировку, а также концепцию основного (Event Loop) цикла событий в Node.

1. Что такое узел?

Node.js — это среда выполнения JavaScript (среда выполнения), основанная на движке Chrome V8. Node — это не язык, который позволяет запускать js во внутренней среде выполнения, и не включает полный набор JavaScript, поскольку он не включен на сервере.DOMиBOM, Node также предоставляет некоторые новые модули, такие как модули http, fs и так далее. Node.js использует事件驱动,非阻塞式 I/Oмодели, что делает ее легкой и эффективной, а менеджер пакетов Node.js, npm, является крупнейшей в мире экосистемой библиотек с открытым исходным кодом. Управляемый событиями и неблокирующий ввод-вывод будут представлены один за другим позже. Пока у нас есть простая концепция node.

2. Какие проблемы решает Node?

Node имеет очевидные преимущества в производительности при работе с сценариями с высоким параллелизмом и интенсивным вводом-выводом.

  • Высокий параллелизм относится к одновременному доступу к серверу в одно и то же время.
  • Интенсивный ввод-вывод относится к операциям с файлами, сетевыми операциями и базами данных и относительно интенсивно использует процессор.

Основной сценой Интернета является получение запроса клиента на чтение статических ресурсов и визуализацию интерфейса, поэтому Node очень подходит для разработки веб-приложений.

3. Процессы и потоки

Процесс – это основная единица операционной системы для распределения ресурсов и планирования задач. Поток – это одноразовая единица выполнения программы, созданная на основе процесса. Процесс может иметь несколько потоков.

3.1 Говоря о браузерах

浏览器模型

  • Пользовательский интерфейс — включает адресную строку, кнопки «вперед/назад», меню закладок и т. д.
  • Механизм браузера — передает инструкции между пользовательским интерфейсом и механизмом рендеринга (основной процесс браузера).
  • Механизм рендеринга, также известный как ядро ​​браузера (процесс рендеринга в браузере).
  • Один плагин соответствует одному процессу (сторонний процесс плагина)
  • GPU улучшает работу в Интернете (процесс GPU)

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

3.2 Движок рендеринга

Механизм рендеринга является многопоточным внутри и содержит два наиболее важных потока: поток пользовательского интерфейса и поток js. Особое внимание следует уделить взаимному исключению ui-потока и js-потока, потому что результат операции JS повлияет на результат ui-потока. Обновления пользовательского интерфейса хранятся в очереди и выполняются, как только поток js простаивает.

3.3 Другие темы

  • Поток триггера события браузера (используется для управления циклом событий, хранения setTimeout, событий браузера, функций обратного вызова ajax)
  • Поток триггера синхронизации (поток, в котором находится таймер setTimeout)
  • Поток асинхронного запроса HTTP (поток запроса ajax)

3.4 js один поток

JavaScript изначально разрабатывался как однопоточный, почему не многопоточный? Разве это не сбивает с толку, если несколько потоков одновременно работают с DOM? Так называемый одиночный поток здесь означает, что основной поток является одним потоком, поэтому основной поток в Node по-прежнему остается одним потоком. Давайте сделаем снимок, чтобы увидеть один поток и многопоток

  • кот, служба iis
    多线程
  • служба узла
    单线程

Однопоточная функция экономит память и не требует переключения контекстов выполнения. И одному потоку не нужно управлять проблемой блокировок, вот краткое введение в концепцию блокировок. Например, все должны ходить в туалет после уроков, а туалет только один, что эквивалентно тому, что все обращаются к одному и тому же ресурсу. Тогда первый, кто войдет, должен быть заперт. И для узла. После занятий я хожу в туалет один, так что проблема запоров отпадает!

4. Очереди и стеки

队列和栈

  • очередь
setTimeout(function(){
    console.log(1)
})
setTimeout(function(){
    console.log(2)
})
setTimeout(function(){
    console.log(3)
})

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

  • куча
function stack(){
    console.log(1);
    fn1();
    function fn1(){
        console.log(2);
        fn2();
        function fn2(){
            console.log(3)
        }
    }
}
stack();

Мы видим, что js выполняется в глобальном контексте, и порядок, в котором стек вызовов помещается в стек, таков: stack->fn1->fn2, Когда область уничтожена, fn2->fn1->stack должен быть уничтожен первым

5. Цикл событий в браузере

eventLoop

  • 1. Все задачи синхронизации выполняются в основном потоке, образуя стек выполнения
  • 2. Помимо основного потока, есть еще и очередь задач. Как только асинхронная задача получает результат выполнения, событие помещается в очередь задач.
  • 3. Как только все задачи синхронизации в стеке выполнения будут выполнены, система прочитает очередь задач, поместит события из очереди в стек выполнения и последовательно выполнит их.
  • 4. Основной поток считывает события из очереди задач, что является непрерывным циклом.

Весь рабочий механизм также называется Event Loop (цикл событий).

6. Цикл событий в узле

Давайте сделаем снимок, чтобы увидеть, как работает узел

node system

  • 1. Код js, который мы напишем, будет передан движку v8 для обработки.
  • 2. В коде может быть вызван nodeApi, и узел будет передан в библиотеку libuv для обработки
  • 3.libuv реализует асинхронный ввод-вывод, блокируя ввод-вывод и многопоточность.
  • 4. В зависимости от событий результаты помещаются в очередь событий и, наконец, передаются нашему приложению.

Внутри libuv есть такой механизм цикла событий. Цикл событий инициализируется при запуске узла

   
   ┌───────────────────────┐
┌─>│     timers(计时器)     │
|  |   执行setTimeout以及   |
|  |   setInterval的回调。  |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     I/O callbacks     |
│  | 处理网络、流、tcp的错误 |
|  | callback              |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
│  │     idle, prepare     │
|  |     node内部使用       |
│  └──────────┬────────────┘      
│  ┌──────────┴────────────┐       ┌───────────────┐ 
│  │       poll(轮询)      │       │   incoming:   │
|  | 执行poll中的i/o队列    | <─────┤  connections, │
|  | 检查定时器是否到时      |       │   data, etc.  |     
│  └──────────┬────────────┘       └───────────────┘    
│  ┌──────────┴────────────┐      
│  │      check(检查)      │
|  | 存放setImmediate回调   |
│  └──────────┬────────────┘
│  ┌──────────┴────────────┐
└──┤    close callbacks    |
   │ 关闭的回调例如         |
   | sockect.on('close')   |
   └───────────────────────┘

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

6.1 этап опроса

poll 流程图

6.2 setTimeout и setImmediate

Они очень похожи, но разница между ними зависит от того, когда они вызываются.

  • Дизайн setImmediate выполняется, когда фаза опроса завершена, то есть фаза проверки;
  • setTimeout предназначен для выполнения, когда этап опроса бездействует, и выполняется после наступления установленного времени; но он выполняется на этапе таймера. Порядок вызова этих двух функций зависит от контекста текущего цикла событий.Если они вызываются вне асинхронного обратного вызова ввода-вывода (вызывается внутри ввода-вывода, поскольку следующий этап — этап проверки), порядок выполнения не определен. , Вам нужно посмотреть на трудоемкую ситуацию перед выполнением цикла.
setTimeout(function timeout () {
  console.log('timeout');
},0);

setImmediate(function immediate () {
  console.log('immediate');
});

6.3 process.nextTick

nextTick не относится к определенному этапу цикла событий, его метод выполнения выполняется в середине переключения каждого этапа, что является отвратительным кодом.

setImmediate(function(){
    console.log(1);
    process.nextTick(function(){
        console.log(2);
    });
});
process.nextTick(function(){
    console.log(3);
    setImmediate(function(){
        console.log(4);
    })
});
// 3 1 4 2

Я не буду объяснять это здесь, если вы это понимаете, вы поймете время выполнения nextTick! (nextTick не должен вызываться рекурсивно, иначе обратный вызов на более позднем этапе не будет выполнен)

7. Макрозадачи и микрозадачи

Задачи можно разделить на макрозадачи и микрозадачи

  • макрозадача: setTimeout, setInterval, setImmediate, ввод-вывод
  • микрозадача: process.nextTick, родной промис (некоторые реализованные промисы помещают метод then в задачу макроса), Object.observe, MutationObserver
process.nextTick > promise.then > setTimeout > setImmediate

Благодаря приведенному выше обучению мы знаем порядок выполнения задач.Следует отметить, что метод Promise.then определен для выполнения после nextTick.

8 Синхронный асинхронный и блокирующий неблокирующий

Синхронные и асинхронные зависят от вызываемого, блокирующие и неблокирующие зависят от вызывающего.

  • Блокирующий вызов означает, что текущий поток приостанавливается до тех пор, пока не будет возвращен результат вызова. Вызывающий поток не возвращается, пока не получит результат.
  • Неблокирующий вызов означает, что вызов не будет блокировать текущий поток до тех пор, пока результат не будет немедленно доступен.

model

До сих пор мы подробно объясняли концепции узла. Если вам это нравится, поставьте лайк ^_^! Поддержите меня, может дать мненаградаКакие