Создание постоянно выполняющегося кода

1

Я создаю родительско-детскую систему с малиной Pi 3 в качестве родителя и серией Arduinos в качестве детей.

Родительские первичные действия - это чтение/запись данных детям через I2C, размещение веб-сервера, хранение/вызов данных от клиента Mongo DB и чтение/запись в GPIO.

То, что я ищу, - это способ иметь мой "главный" кусок кода навсегда, подобно тому, как работает код в функции Arduino loop().

Я знаю, что while (true) циклы - нет-нет, но я опасаюсь использовать setTimeout для запуска этого повторного выполнения, потому что мой код имеет значительно отличающееся время выполнения в зависимости от I2C и базы данных.

Будет ли библиотека навсегда или PM2 служить мне здесь?

  • 0
    Если ваш код является чисто синхронным, я не могу представить причину, по которой вы не должны использовать while(true) . Вы должны подумать о том, что нужно импортировать: хотите ли вы убедиться, что итерация заканчивается до начала следующей, или речь идет о выполнении кода через определенный интервал?
  • 0
    К сожалению, вот где все становится липким. Почти все в коде является асинхронным (например, чтение / запись I2C и обновления MongoDB). Все асинхронные вещи находятся / будут позади, если операторы с некоторой логической логикой гарантируют, что он вызывается только тогда, когда это должно быть. Я просто думаю об этом неправильно? Есть ли лучший способ сделать это, просто попытаться сделать все на основе событий? Я родом из страны программирования ПЛК, где вам приходится писать асинхронный код в среде, которая работает синхронно, и, возможно, отсюда и моя путаница.
Теги:
repeat
raspberry-pi

2 ответа

1
Лучший ответ

Прежде всего, как навсегда, так и на PM2 - это CLI, и для поддержания процессов они автоматически перезапускаются, когда это необходимо. Если я правильно понял это, вы хотите повторить кусок кода, а не процесс, так что вот решение о том, как это сделать, учитывая, что вы используете много асинхронного кода:

async function loop() {
  /*
    Do everything you want to do in one iteration inside this function
    and use the 'await' keyword to wait for Promises to resolve. If you use
    libraries that don't support Promises yet, look for a wrapper that uses
    them (often called "xy-as-promised") or use 'require('util').promisify()'.
  */
}

async function startLoop() {
  while(true) await loop()
}

startLoop()
  • 1
    Спасибо за ответ. Я использую Bluebird, чтобы обещать все, что очень полезно. Поэтому у меня сложилось впечатление, что в то время как (правда) бесконечные циклы могут привести к блокировке вашего кода. Что такое использование async / await в том, что предотвращает проблемы с производительностью while (true)?
  • 0
    Если вы удалите await через await while(true) , функция loop будет вызываться повторно. Разница в том, что с помощью await вы можете убедиться, что последняя итерация завершена (асинхронная функция / Promise разрешена) до запуска новой, поэтому вы не тратите память и вычислительные мощности на одновременное выполнение нескольких итераций.
Показать ещё 1 комментарий
1

@Niklas имеет интересный подход, используя новую async/await парадигму. Однако, если вы хотите придерживаться "хорошей" старой моды JS (или вооруженная обезьяна заставляет вас использовать ее), следующее должно удовлетворять упомянутой обезьяне:

function asyncStuff() {
    // if doStuff() returns a promise, just return it.  However, I'm assuming here that doStuff() uses a error-first callback common in NodeJS.
    return new Promise(function(resolve, reject) {
        doStuff(function errorFirstCallback(error) {
            if(error) {
                return reject(error);
            }

            resolve();
    });
};

function loop() {
    return asyncStuff().then(loop);
}

loop();

В принципе, вы создаете бесконечный цикл, используя обещания. loop() вызывает asyncStuff() и ожидает выполнения обещания. По завершении обещания loop() вызывается снова. Нет необходимости использовать while ES6.

Один из интересных аспектов этого фрагмента - вы не будете переполнять стек из-за рекурсивного вызова loop(). Круто, да?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню