Я хотел бы выполнить какую-то сколь угодно дорогую работу со сколь угодно большим набором файлов. Я хотел бы сообщать о прогрессе в реальном времени, а затем отображать результаты после обработки всех файлов. Если нет файлов, соответствующих моему выражению, я хотел бы выдать ошибку.
Представьте себе, что вы пишете тестовую среду, которая загружает все ваши тестовые файлы, выполняет их (в произвольном порядке), сообщает о прогрессе в режиме реального времени, а затем отображает совокупные результаты после завершения всех тестов.
Написание этого кода на языке блокировки (например, на Ruby) чрезвычайно просто.
Как оказалось, у меня проблемы с выполнением этой, казалось бы, простой задачи в узле, и при этом я действительно использую преимущества асинхронного ввода-вывода на основе событий.
Моим первым замыслом было выполнение каждого шага последовательно.
- Загрузите все файлы, создав набор файлов для обработки
- Обработка каждого файла в коллекции
- Сообщить о результатах после обработки всех файлов
Этот подход работает, но мне он не совсем подходит, поскольку он заставляет более дорогостоящую вычислительную часть моей программы ждать завершения ввода-вывода всех файлов. Разве это не ожидание, которое Node был разработан, чтобы избежать?
Мой второй дизайн - обрабатывать каждый файл так, как он был асинхронно найден на диске. Для аргументации давайте представим метод, который выглядит примерно так:
eachFileMatching(path, expression, callback) {
// recursively, asynchronously traverse the file system,
// calling callback every time a file name matches expression.
}
И потребитель этого метода выглядит примерно так:
eachFileMatching('test/', /_test.js/, function(err, testFile) {
// read and process the content of testFile
});
Хотя этот дизайн выглядит как очень «нодальный» способ работы с IO, он страдает от 2 основных проблем (по крайней мере, в моей предположительно ошибочной реализации):
- Я не знаю, когда все файлы были обработаны, поэтому я не знаю, когда собирать и публиковать результаты.
- Поскольку чтение файлов неблокирующее и рекурсивное, я пытаюсь понять, не было ли найдено файлов.
Я надеюсь, что я просто делаю что-то не так, и есть какая-то достаточно простая стратегия, которую другие люди используют, чтобы второй подход работал.
Несмотря на то, что в этом примере используется тестовая среда, у меня есть множество других проектов, которые сталкиваются с этой же проблемой, и я думаю, что любой, кто пишет достаточно сложное приложение, которое обращается к файловой системе в узле, тоже будет.