Рубрики
Без рубрики

Как использовать таймеры и события в Node.js

Автор оригинала: Tendai Mutunhire.

События и таймеры в Node.js

Node.js имеет несколько утилит для обработки событий, а также планирование выполнения кода. Эти утилиты, объединенные, дают вам возможность реагировать реагировать в нужное время, например:

  • Очистка данных сеанса Когда пользователь выходит из системы
  • Планирование тайм-аута для получения результатов из вызова API и указание кода обработки ошибок для запуска в случае тайм-аута
  • Закрытие соединений базы данных до выхода из Node.js

В этой статье мы перейдем на то, как таймеры Работа в Node.js. Мы также представим, как работает петли событий Node.js и как вы можете воспользоваться преимуществами возможностей обработки событий узла.

Таймеры

Первый набор утилит, на которых мы рассмотрим Сетримс , Setimmediate и Setinterval Сроки утилит. С помощью этих инструментов мы можем контролировать время выполнения кода.

Почему это будет важно? В Node.js, аналогично при использовании других языков программирования, таких как C, Python, Java и другие, это помогает запланировать определенные функции для прохождения несколько раз.

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

сентиментальный

С Сетримс , мы можем запланировать код для выполнения после определенной продолжительности времени.

// setTimeout.js

let cue = 'The actors are here!';

// However, the cue is not announced until at least 5000ms have
// passed through the use of setTimeout
setTimeout(function() {
    return console.log(cue);
}, 5000);

// This console log is executed right away
console.log('An exploration of art and music. And now, as we wait for the actors...');

Чтобы выполнить этот код и увидеть его в действии, запустите Узел Settimeout.js На вашем терминале:

$ node setTimeout.js
An exploration of art and music. And now, as we wait for the actors...
The actors are here!

Обратите внимание, как даже если Консоль («разведка ...») Звонок – это после наше console.log (que) Звоните, он все еще выполнен в первую очередь.

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

setinterval.

В ситуациях, когда вам нужно повторить, регулярное, выполнение кода, например, длинный опрос, то Setinterval Метод будет более естественным подходом, чем Сетримс Отказ С помощью этой функции мы можем указать функцию, которая должна выполняться каждые x секунды. Функция на самом деле принимает свой аргумент в миллисекундах, поэтому вы должны сделать преобразование себя перед входом в свои аргументы.

Предположим, что мы хотим проверить длину очереди на дисковод McDonald, поэтому пользователи нашей программы могут развеваться в лучшем времени. Использование Setinterval , мы можем многократно проверять длину очереди и сказать им, когда побережье ясно.

// setInterval.js

// This function simulates us checking the length
// of a McDonald's drive-through queue
let getQueueLength = function() {
    return Math.round(12 * Math.random());
};

// We would like to retrieve the queue length at regular intervals
// this way, we can decide when to make a quick dash over
// at the optimal time
setInterval(function() {
    let queueLength = getQueueLength();

    console.log(`The queue at the McDonald's drive-through is now ${queueLength} cars long.`);

    if (queueLength === 0) {
        console.log('Quick, grab your coat!');
    }

    if (queueLength > 8) {
        return console.log('This is beginning to look impossible!');
    }
}, 3000);

Вы можете увидеть вывод ниже. Запустите код с Узел setinterval.js , как показано ниже:.

$ node setTimeout.js 
The queue at the McDonald's drive-through is now 6 cars long.
The queue at the McDonald's drive-through is now 0 cars long.
Quick, grab your coat!
The queue at the McDonald's drive-through is now 1 cars long.
The queue at the McDonald's drive-through is now 3 cars long.
The queue at the McDonald's drive-through is now 9 cars long.
This is beginning to look impossible!
The queue at the McDonald's drive-through is now 0 cars long.
Quick, grab your coat!
The queue at the McDonald's drive-through is now 10 cars long.
This is beginning to look impossible!

свидетельствовать

Если бы мы хотели, чтобы функция была выполнена как можно более срочно, мы используем Setimmediate Отказ Функция, которую мы выполняем таким образом, будет выполнять перед собой Сетримс или Setinterval Вызывы, как только текущий цикл событий Node.js закончил вызов вызывающих событий.

Вот пример этого в процессе. Вы можете запустить этот код с помощью команды Узел setimmediate.js.

// setImmediate.js

// A timeout
setTimeout(function() {
    console.log('I am a timeout');
}, 5000);

// An interval
setInterval(function() {
    console.log('I am an interval');
}, 5000);

// An immediate, its callback will be executed before those defined above
setImmediate(function() {
    console.log('I am an immediate');
});

// IO callbacks and code in the normal event loop runs before the timers
console.log('I am a normal statement in the event loop, guess what comes next?');
$ node setImmediate.js 
I am a normal statement in the event loop, guess what comes next?
I am an immediate
I am a timeout
I am an interval
I am an interval
I am an interval
...

Setimmediate Обратный вызов, хотя определен после те для Setinterval и Сетримс , будет бежать впереди них.

Контур событий

Вопрос, который могло бы произойти вам: «Как Node.js отслеживает все эти времена, таймеры и события? Как порядок исполнения приоритетов?» Это хорошая линия запроса и требует, чтобы посмотреть на что известное как «контур событий Node.js».

Итак, какая петля событий?

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

Контур событий имеет следующие основные этапы:

  • Таймеры – выполняет обратные вызовы, которые были запланированы с Сетримс и setinterval.
  • Ожидающие обратных вызовов – выполняет любые обратные вызовы, которые готовы к запуску
  • Простой, готовят – внутреннее в Node.js
  • Опрос – принимает входящие соединения и обработка данных
  • Проверьте – призывает обратные вызовы, установленные с помощью свидетельствовать
  • Закрыть обратные вызовы – запускает обратные вызовы для закрытых событий

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

Отвечая на асинхронные возвращения с обратными вызовами

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

Как процессы этих операционных систем взаимодействуют с процессом Node.js? Через средства обратных вызовов. Мы используем обратный вызов для асинхронного процесса вещей на заднем плане, затем подключитесь к контуре события после завершения асинхронного задания. Чтобы получить этот вид функциональности на других языках программирования, вы можете использовать очередь задач, как Сельдерей в Python или Sidekiq в рубине. В Node.js, поскольку цикл событий и асинхронное исполнение Node.js уже включается в очередь для вас, вы получаете эту асинхронную обработку бесплатно.

Чтобы увидеть обратные вызовы в действии, мы собираемся прочитать файл из файловой системы и используйте обратно, чтобы распечатать содержимое.

Первый шаг – создать файл. В этом случае мы используем текстовый файл, содержащий линии к стихотворению T.S. Элиот. Вы можете заменить свой собственный файл. Этот файл называется poem.txt И вы можете поместить следующее содержимое в него.

// poem.txt

Macavity - The Mystery Cat, by T. S. Eliot

Macavity's a Mystery Cat: he's called the Hidden Paw--
For he's the master criminal who can defy the Law.
He's the bafflement of Scotland Yard, the Flying Squad's despair:
For when they reach the scene of crime--Macavity's not there!

Macavity, Macavity, there's no on like Macavity,
He's broken every human law, he breaks the law of gravity.
His powers of levitation would make a fakir stare,
And when you reach the scene of crime--Macavity's not there!
You may seek him in the basement, you may look up in the air--
But I tell you once and once again, Macavity's not there!

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

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

// readFile.js

const fs = require('fs');

// Attempt to read the poem file
// Attach a callback to handle a successful read and print the contents to console
fs.readFile('./poem.txt', 'utf-8', function(err, data) {
    if (err) return console.error(err);

    let poem = data.toString();
    console.log('Here is the poem of the day...\n\n');
    return console.log(data);
});

Запустите этот код с помощью Узел readfile.js Отказ Файл будет прочитан, а консоль должна печатать вам поэм. Если нет, это распечатает ошибку, которая была встречена, например, если такого файла нет на указанном пути.

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

Отвечая на события с слушателями событий

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

Объекты, которые обычно выделяют эти события, расширяют базу Eventemitter объект, который исходит из встроенного События модуль.

Ваше заявление может ответить на эти события через механизм слушателей событий. Как правило, вы прикрепляете слушатель события в коде посредством средств ключевого слова «ON», а затем строку, указав тип события, а затем, наконец, функция, которая является кодом для выполнения при возникновении события.

Чтобы прослушать слушателей событий в действии, мы собираемся создать сервер, который взаимодействует с API CAT и ответами Parse от API. Затем наш сервер будет обслуживать запросы и демонстрирует поиск посетителей «Cat of Day». События, с которыми мы будем работать, являются частью http . модуль.

Мы также будем использовать Модуль XML2JS Чтобы разбирать ответы XML, что API CAT производит. Чтобы установить XML2JS , вы захотите запустить команду NPM Установите XML2JS в подходящем каталоге проекта.

Как только вы установили модуль, создайте два файла в каталоге, Cats.html и Cats.js Отказ Внутри Cats.html Поместите переднюю часть нашего приложения. Это просто отобразит данные CAT, которые мы собираемся распределять.





  
    
    
    

    Cats

    
    
    

    
    
    
  
  

    

Cats Of Silicon Valley

Welcome to the Cat Of The Day

Responsive image

More Cats!

Основная часть нашей логики будет на стороне сервера, который работает с слушателями событий. Это содержится в Cats.js файл. Чтобы увидеть код слушателя событий в действии, поместите следующий код в файл, затем запустите его с помощью Узел Cats.js И в вашем браузере посетите http://localhost: 4000 Отказ

// cat.js

const http = require('http');
const fs = require('fs');
const xml2js = require('xml2js');

// We will get images from the CatAPI https://thecatapi.com/
let catApi = 'http://thecatapi.com/api/images/get?format=xml&results_per_page=1';

let catUrl = '';
let catSource = '';

let server = http.createServer(function(req, res) {
    // Get fresh cat data from the Cat API
    http.get(catApi, (res) => {
        let data = '';
    
        // Attach event listener for when receiving data from the remote server is complete
        res.on('end', () => {
            console.log('***We have completed cat data\n***');
            console.log(data);
      
            let parser = new xml2js.Parser();
            return parser.parseString(data, function(err, imgxml) {
                if (err) {
                    return console.log('Error parsing cat data');
                } else {
                    let imgjson = JSON.parse(JSON.stringify(imgxml));
        
                    console.log('***We have cat JSON***');
                    console.log(imgjson);
        
                    catUrl = imgjson.response.data[0].images[0].image[0].url[0];
                    return catSource = imgjson.response.data[0].images[0].image[0].source_url[0];
                }
            });
        });
    
        // Event listener for the 'data' event
        // In this case, accumulate all the data so we can use it all at once later
        return res.on('data', (xml) => {
            return data += xml;
        });
    });

    // Serve cat images from the CatAPI
    return fs.readFile('./cats.html', function(err, cathtml) {
        if (err) {
            console.error(err);
            return res.end('An error occurred');
        }
    
        let html = cathtml.toString()
                          .replace('IMGSRC', catUrl)
                          .replace('SOURCE', catSource);
    
        res.writeHead(200, {
            'Content-Type': 'text/html'
        });
    
        res.write(html);
        return res.end();
    });
});

// Run the server
server.listen(4000);

Ниже мы входим в код в деталях. Также посмотрите на комментарии в коде.

Как вы можете видеть из кода, наша запрос на API CAT запрашивает новые данные CAT. Затем мы даем исполнение Node.js продолжается как обычно. Однако мы прилагаем два слушателя событий, чтобы иметь дело с новыми событиями с удаленного API. Первый из них – слушатель событий «на конец». Когда у нас есть полная полезная нагрузка CAT от API CAT, мы тогда обновляем нашу страницу с новыми данными и изображением. Второй класс мероприятия мы слушаем, – это событие «Данные». Это срабатывает, когда есть новые данные с удаленного хоста. В этом случае мы буксируем данные и добавьте его в наш временный хранилище данных.

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

Кошка дня 1

Посетители нашего сайта могут получить новую кошку изображений дня по телефону кнопки.

Кошка дня 2

В Node.js есть гораздо больше событий и таймеров, чем то, что мы описали здесь. Хорошая следующая тема для изучения – это Эмиттеры событий , что дает вам еще больше власти над видами событий, которые может использовать ваше приложение.