LINUX.ORG.RU

Как зациклить код на nodejs?

 ,


0

1

Короче есть скрипт на nodejs. Надо, чтобы после полной его отработки он запускался снова и так до морковкина заговения.
while(true) не подходит, т.к. запускает не последовательно, а все параллельно, а мне надо, чтоб запускался только после завершения.
Как это правильно сделать?

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)

Гы-гы

while true; do node script.js && sleep 1; done
EXL ★★★★★
()
Ответ на: комментарий от znenyegvkby

https://www.npmjs.com/package/forever

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

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от Qwentor

т.к. его надо закрывать после вставки всего нужного, а как отловить этот момент, когда все отработало - не понимаю.

Ничего не понял. Зачем что-то отлавливать? Взял и закрыл соединение, когда все сделал. В чем проблема-то? :)

znenyegvkby
()

можешь запустить сервер, который будет принимать сообщения от твоего скрипта. Когда скрипт заверщается, он должен будет отправить сообщение серверу, что он завершился, после чего сервер через какой-то таймаут его запускает. Либо, можно проще сделать. Сервер постоянно мониторит ps -al и как только процесс исчезает, он его перезапускает

xlsparse
()
Ответ на: комментарий от xlsparse

Короче так: у меня скрипт посылает много запросов на вставку данных в MySQL - надо понять когда пройдут все запросы и закрыть соединение.

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от xlsparse

асинхронные. спс, сейчас посмотрю о чем ты

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от xlsparse
Promise.all([
  httpGet('/article/promise/user.json'),
  httpGet('/article/promise/guest.json'),
  httpGet('/article/promise/no-such-page.json') // (нет такой страницы)
]).then(
  result => alert("не сработает"),
  error => alert("Ошибка: " + error.message) // Ошибка: Not Found
)


Это отсюда https://learn.javascript.ru/promise
Но у меня нет просто нескольких функций с connection.query , которые можно запихнуть в массив. У меня куча кода (парсер) с вложенными forEach и async.each , а здесь требуется вернуть какое-то значение по одному на функцию, чтобы перейти к then - у меня это не выйдет, т.к. все в цикле. Что-то можно в этом случае сделать?

Qwentor ★★★★★
() автор топика
Последнее исправление: Qwentor (всего исправлений: 1)

Как зациклить код на nodejs?

Просто напиши его, все остальное он сделает сам.

ya-betmen ★★★★★
()
Ответ на: комментарий от Qwentor

даже не знаю. Promise.all работает с промисами, иначе никак, наверное. есть вариант на коллбеках еще написать, тогда из последнего коллбека закрывать. Но тут в любом случае надо код соответствующий генерировать или писать.

xlsparse
()
Ответ на: комментарий от Qwentor

мимокрокодил: видел еще такое:

...
)
.then(function(p){...})
.then(function(p2){...})
.error(function(e){...})
.catch(function(err){...});

anTaRes ★★★★
()
Ответ на: комментарий от xlsparse

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


var connection = mysql.createConnection({
  host     : '127.0.0.1',
  user     : 'root',
  password : 'password',
  database : 'database'
});

connection.connect(); 

var obj = {};
obj.one = 'http://blablabla'; //big big big json
obj.two = 'http://blablabla'; //big big big json
obj.three = 'http://blablabla'; //big big big json

function doparse(url){

//Тут получаем данные json по url и преобразуем их в объект 

body = JSON.parse(body);

var events = body['events'];

async.each(events, function(event, callback){

	var markets = event['markets'];
	markets.forEach(function(market){

		var runners = market['runners'];
		runners.forEach(function(runner){
			prices = runner['prices'];
			prices.forEach(function(price){


				var inserted_data = [...........]; //вставляемые данные

				connection.query('INSERT blablabla', inserted_data, function(err, result){

					//Обработка ошибок и просто console.log

				});

			});


		});




	});


});







}

async.each(obj, function(url, callback){
				
     doparse(url);
})

Куда тут корректно ставить connection.end() ?

Qwentor ★★★★★
() автор топика
Последнее исправление: Qwentor (всего исправлений: 3)
Ответ на: комментарий от Qwentor

* загугли экспресс,
* запусти его установочную прогу и будет тебе минимальный в цыкле выполняющийся сервер
* убери connection.connect(); заюзай require('sequelize'); , это добавит фичей и сложности но (а хз) избавит от создания/открытия/закрытия/валидации/...

т.е. грубо говоря это хеловорлд экспресса, + твой INSERT blablabla

сервер выполняет его пока не зафейлится, против фейлов юзают демоны (типо forever)

вои и все что я знаю о ноде, если где не прав - буду благодарен за поправки

anTaRes ★★★★
()
Ответ на: комментарий от Qwentor

попробуй вот по этому образцу


promises = []

test = function(fileName){
   [1, 2, 3, 4, 5].forEach(function (){
       promises.push(new Promise(function(resolve, reject){
           fs.readFile(fileName, "utf8", function(err, data){
              if(err) return reject(err)
              resolve(data)
           })
       }))
   })
}

test("file")

Promise.all(promises)
  .then(function(data){console.log("end")}) // here is your connection.close()
  .catch(function(err){console.log(err)})

суй в предпоследнем внутреннем колбеке промисы в массив, где то тут:

prices.forEach(function(price){
В коллбеке then закрывай соединение

Только форичи лучше все на синхронные как то переделать.

xlsparse
()
Ответ на: комментарий от xlsparse

Сделал так - оно мне сразу прерывает соединение и не работает( Асинхронность обязательна - нужна скорость

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от Qwentor

А теперь быстро идешь и читаешь доку по async.
Hint #1: после завершения обработки каждого элемента ты должен вызывать callback, который async тебе дал.
Hint #2: async.each третьим аргументом принимает коллбэк, который вызывается после завершения обработки всей коллекции.

unikoid ★★★
()
Последнее исправление: unikoid (всего исправлений: 1)
Ответ на: комментарий от unikoid

Hint #2

если внутри async.each обращение к бд со вставкой данных, он будет ждать завершения запросов или пробежит по циклу и вызовет этот самый колбэк ничего не дожидаясь и оборвав соединение? По-моему второе, если не ошибаюсь, потому как вроде пробовал уже так, но попробую еще

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от unikoid

То бишь мне его вызывать внутри connection.query()?

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от unikoid

Error: Callback was already called

Это из-за цикла

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от unikoid

И мне то нужно, чтобы коллбэк вызывался после

async.each(obj, function(url, callback){
				
     doparse(url);
})



Как это сделать? Если просто после doparse(url) вызвать коллбэк, то оно самое и происходит - прерывается раньше времени

Qwentor ★★★★★
() автор топика
Ответ на: комментарий от Qwentor

В общем, я сегодня зачем-то очень добрый, поэтому постараюсь объяснить все на пальцах.
1. async.each принимает три параметра: коллекцию, обработчик коллекции и коллбэк, который вызывается по завершении обработки всей коллекции.
2. async ничего не знает и не может знать про твой асинхронный код и понятия не имеет, когда он завершится. Поэтому вместе с каждым элементом коллеции он дает тебе одноразовый коллбэк. Вызывая этот коллбэк ты говоришь async'у, что ты закончил обработку этого элемента коллекции. После того, как ты вызовешь коллбэк, соответствующий каждому элементу коллекции - async считает, что ты ты закончил обработку всей коллекции и вызывает соотв. коллбэк данный тобой.
Про обработку ошибок - почитаешь сам, это тоже отдельная история.

В твоем случае есть многоуровневая вложенность коллекций (url->events->markets->runners->prices). Соответственно, тебе нужно либо сделать эту вложенность плоской, получив на выходе итоговый массив операций для каждого набора {url, event, market, runner, price} и затем по нему пробежаться через async.each, либо у тебя обработка КАЖДОГО уровня вложенности представляет собой асинхронную операцию (потому что асинхронной является обработка последнего уровня) и ты должен по каждой вложенной коллекции бежать через async.each (выглядит как ад, если честно).

Надеюсь, дальше ты поймешь сам.
Про промисы почитаешь сам, они схожи с async'ом, но есть свои радости и свои боли.

unikoid ★★★
()
Ответ на: комментарий от unikoid

Типа так (псевдокод)

async.each(urls, (url, cb0) => {
    async.waterfall([
        cb1 => {
            getSomeData(url, (e, data) => {
                if(e) { return cb1(e); }
                return cb1(null, JSON.parse(data));
            });
        },
        (events, cb2) => {
            async.each(events, (event, cb3) => {
                async.each(event.markets, (market, cb4) {
                    // Если нужно больше вложенности - продолжаем, иначе
                    conn.insert(event, market, cb4);
                }, cb3);
            }, cb2);
        }
    ], cb0);
}, (err) => {
    if(err) {
        ...
    }
    conn.close();
    console.log('Done');
});

unikoid ★★★
()
Ответ на: комментарий от unikoid

О, спасибо! Только что именно так и сделал почти! Работает!
Всем спасибо за разъяснения. В особенности unikoid и xlsparse, а также anTaRes

Qwentor ★★★★★
() автор топика

Эталонный тред переписи быдлокодеров!

boombick ★★★★★
()

				});

			});


		});




	});


});

ох блджад.

ggrn ★★★★★
()
function some()
{
// то что зациклить
setTimeout(some,0);
}
some();
sholom
()
Ответ на: комментарий от Qwentor

Это выпендрёжь про многопоточность, не обращай внимание - к делу это не относится. Самое интересное, что задача элементарная, но сейчас насоветуют «святых коров».

menangen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.