2017-01-18 4 views
0

Я создал webscraper с cheerio и request, и теперь я пытаюсь реализовать цикл на массиве url.Функция и цикл обратных вызовов Javascript/NodeJS

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

Это мой код:

var getWebData = function(url) { 
    var i = 1; 
    var data = []; 
    for (c = 0; c < url.length; c++) { 
    data[i] = request(url[c], function(err, resp, body) { 
      console.log('ok'); 
      if (!err) { 
      console.log('there'); 
      var $ = cheerio.load(body); 
      $('.text').each(function(i, element) { 
       var jsObject = { name : "", description : "", price: "", categorie: "", pricePerKg: "", capacity: "", weight: "", scrapingDate : "", url: ""}; 
       var name = 'TESTOK'; 
       jsObject.name = name; 
       data.push(jsObject); 
      }) 
      return data; 
     } 
     console.log('but'); 
     }); 
    i++; 
    } 
    var json = JSON.stringify(data); 
    fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) { 
     console.log('File successfully written!'); 
    }) 
} 

getWebData(url); 
app.listen('8080'); 

Примечание, чем любой из моих отлаживает печати не печатаются.

Кто-нибудь знает, что не так в моем коде и как я могу это сделать, чтобы заставить его работать?

+0

- это 'url' список? – eLRuLL

+0

«Обратите внимание, что любая печать моего отладки напечатана ...» - Что напечатано? Кроме того, 'data' будет неопределенным в' JSON.stringify (data) ', потому что вы не учитываете асинхронность. –

+0

url является [] url @eLRuLL – rastafalow

ответ

1

запрос Асинхронный

var json = JSON.stringify(data); 
fs.writeFile('output.json', JSON.stringify(json, null, 4), function(err) { 
    console.log('File successfully written!'); 
}) 

Это выше код работает до цикл completetes выполнения и заполнит объект данных. Попробуйте выполнить этот кусок кода при завершении цикла.

запустить эту команду первой НПМ установки асинхронной --save

var async = require('async'); 

    var getWebData = function(url){ 
    var data = []; 
    async.eachSeries(url, function(urlSingle , cb){ 
     request(urlSingle, function(err, resp, body) { 
     //write your logic here and push data in to data object 
     cb(); 
     }) 
    },function(){ 
    // this will rum when loop is done 
    var json = JSON.stringify(data); 
     fs.writeFile('output.json', JSON.stringify(json, null, 4),   function(err) { 
      console.log('File successfully written!'); 
     }); 
    }); 
    } 
+0

Спасибо за ваш ответ. Асиф Саид, не могли бы вы рассказать мне, как это сделать? – rastafalow

+0

проверить обновленный ответ –

+0

Большое спасибо Asif, можете ли вы рассказать мне, где мне нужно увеличить свою переменную c? Похоже, из звонка с просьбой? – rastafalow

1

Я читал ответ Асиф в и комментарии. Эта реализация верна, но вам не нужно увеличивать переменную c, также, если вы начинаете c = 0 раньше, все запросы будут связаны с URL [0].

отмечают, что async.eachSeries обратные вызовы каждый элемент массива URL в «urlsingle» обратного вызова, так что вы должны использовать

request(urlsingle, ... 

или рассмотреть возможность использования async.eachOf, который дает вам индекс каждого элемента в массиве ,

проверка асинхронной документации для каких-либо сомнений http://caolan.github.io/async/

0
for (c = 0; c < url.length; c++) { 
    …… 
} 

вы должны изменить следующий образом:

var async = require('asycn'); 
async.map(url, 
function(item, callback) { 
    data[i] = request(url[c], 
    function(err, resp, body) { 
     console.log('ok'); 
     if (!err) { 
      console.log('there'); 
      var $ = cheerio.load(body); 
      $('.text').each(function(i, element) { 
       var jsObject = { 
        name: "", 
        description: "", 
        price: "", 
        categorie: "", 
        pricePerKg: "", 
        capacity: "", 
        weight: "", 
        scrapingDate: "", 
        url: "" 
       }; 
       var name = 'TESTOK'; 
       jsObject.name = name; 
       data.push(jsObject); 
      }) callback(err, data); 
     } 
     console.log('but'); 
    }); 
    i++; 
},function(err, results) { 
    if(err){ 
     console.log(err); 
    } 
}); 

в цикле является трудоемким operation.you следует использовать асинхронные операции.

Смежные вопросы