Я создаю родительско-детскую систему с малиной Pi 3 в качестве родителя и серией Arduinos в качестве детей.
Родительские первичные действия - это чтение/запись данных детям через I2C, размещение веб-сервера, хранение/вызов данных от клиента Mongo DB и чтение/запись в GPIO.
То, что я ищу, - это способ иметь мой "главный" кусок кода навсегда, подобно тому, как работает код в функции Arduino loop().
Я знаю, что while (true) циклы - нет-нет, но я опасаюсь использовать setTimeout для запуска этого повторного выполнения, потому что мой код имеет значительно отличающееся время выполнения в зависимости от I2C и базы данных.
Будет ли библиотека навсегда или PM2 служить мне здесь?
Прежде всего, как навсегда, так и на 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()
await
через await
while(true)
, функция loop
будет вызываться повторно. Разница в том, что с помощью await
вы можете убедиться, что последняя итерация завершена (асинхронная функция / Promise разрешена) до запуска новой, поэтому вы не тратите память и вычислительные мощности на одновременное выполнение нескольких итераций.
@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()
. Круто, да?
while(true)
. Вы должны подумать о том, что нужно импортировать: хотите ли вы убедиться, что итерация заканчивается до начала следующей, или речь идет о выполнении кода через определенный интервал?