LINUX.ORG.RU
function scrapeArticleLinks(category) {
    for (var i = 1; i <= category.pages; i++) {
        scrapeArticles(BASE_URL + category.href + '?page=' + i);
    }
}
 
function scrapeArticles(article_url) {
    request(article_url, function(error, response, body) {
        if (!error) {
            console.log(body);
        }
    });
}
trupanka
() автор топика
Ответ на: комментарий от ZuBB

А взять и помочь человеку? Для разнообразия.

trupanka
() автор топика
Ответ на: комментарий от trupanka
function scrapeArticleLinks(category) {
    for (var i = 1; i <= category.pages; i++) {
        //задержка scrapeArticles на 1 секунду
        setTimeout(scrapeArticles(BASE_URL + category.href + '?page=' + i),1000)
    }
}
 
 function scrapeArticles(article_url) {
    request(article_url, function(error, response, body) {
        if (!error) {
            console.log(body);
        }
    });
}

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

В этом и проблема. Это не сработает, scrapeArticles отработает моментально, т.к. request асинхронный.

И хоть 100, хоть 1000 запросов будут идти один за другим. Фактически задержка в 1 секунду будет только перед первым запросом.

Задача не так проста, как кажется.

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

Еще у тебя и ошибка. Нужно обернуть setTimeout в функцию, чтобы было замыкание с правильным i.

setTimeout(scrapeArticles(BASE_URL + category.href + '?page=' + i), i * 1000)

Такой вариант тоже не устраивает, т.к. после нескольких итераций начинаются ошибки. Хотя может это на сервере проверки не только на кол-во соединений.

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

Как вариант. Буду иметь в виду, если не получится обойтись без создания массива.

Просто у меня еще `scrapeArticleLinks` зачем-то вызывается асинхронно. В 10 потоков.

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

Т.е. нужно еще как-то подождать, пока эти 10 потоков забьют массив ссылками, прежде чем делать pop/request-ы

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

Пока лучшее, что удалось нагородить... использование очереди из async не по назначению, и request c timeout.

Такой вариант отрабатывает каждую секунду определенное кол-во запросов, но если случаются проблемы во время запроса, то вообще все падает с `max call stack` в async-е.

Вот этот говнокод:

var q = async.queue(function (page, callback) {
    scrapeArticles(page);
    callback();
}, 2);
 
q.drain = function() {
   console.log('All items have been processed');
}
 
function scrapeArticleLinks(category) {
    for (var i = 1; i <= category.pages; i++) {
        var page = BASE_URL + category.href + '?page=' + i;
        q.push(page, function (err) {
            if (err) {
                console.error('Error while processing ' + page);
            }
        });
    }
}
 
var counter = 0;
 
function scrapeArticles(page) {
    counter++;
    setTimeout(function() {
        request(page, function(error, response, body) {
            if (!error) {
                    console.log(body);
            } else {
                console.error('Error while requesting ' + page);
            }
        });
    }, 1000 * counter);
}

Должно быть какое-то решение проще в мире асинхронного программирования, наверное.

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

Да. Выкинул async, все вроде работает в таком виде...

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

Вроде бы напрашивается генератор

 
scrapeArticles = function(article_url) {
   return new Promise(function(resolve, reject){
    request(article_url, function(error, response, body) {
        if(error) return reject(error)
        resolve(body)
    });
  })
}


process = function(generator){
    var next = generator.next()

    if(!next.done) next.value.then(
       function(data){console.log(data); process(generator)},
       function(error){console.log(error)}
    )
}

process(function*(){
  for(var i = 1; i <= category.pages; i++){
   yield scrapeArticles(BASE_URL + category.href + '?page=' + i)
  }
}())


Как то так.

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