2016-02-26 8 views
1

Я новичок в Node.js, и я занимаюсь использованием Filestreams and Requests. Я написал программу, которая получает HTML-код форума reddit и фильтрует его, чтобы получить заголовок всех сообщений. Мой код выглядит следующим образом:Фильтрация запроса трубы Node.js

var request = require('request'); 
var http = require('http'); 
var fs = require('fs'); 

var server = http.createServer(); 

server.on('request', function(req, response){ 
    var matches = []; 
    var desination = fs.createWriteStream("posts.txt"); 
    request('https://www.reddit.com/r/TagPro/top/?sort=top&t=all', function (error, response, body) { 
     if (!error && response.statusCode == 200) { 
      var re = /tabindex="1" >(.+?)</g; 
      var match; 
      while (match = re.exec(body)) { 
       matches[matches.length] = match[1]; 
      } 
     } 
    }).pipe(response); 

}); 

server.listen(8080) 

В основном массив matches держит отфильтрованную информацию, и я пытаюсь трубы ее содержимое в ответ на запрос сервера.

Прямо сейчас мой код переводит весь html в ответ, но мне было интересно, могу ли я просто передать содержимое моего массива, чтобы была записана только полезная информация.

ответ

1

Фактически вы обрабатываете ответ дважды: используя обратный вызов (в котором вы извлекаете совпадения) и, отправив его в ответ HTTP (без изменений).

Вместо этого вы должны выбрать тот или иной. Проще всего было бы не трубы данных вообще, а просто отправить обратно ответ (JSON), как только вы накопили все матчи:

server.on('request', function(req, res) { 
    var matches = []; 
    request('https://www.reddit.com/r/TagPro/top/?sort=top&t=all', function (error, response, body) { 
    // Handle errors properly. 
    if (error || response.statusCode !== 200) { 
     return res.writeHead(error ? 500 : response.statusCode); 
    } 

    // Accumulate the matches. 
    var re = /tabindex="1" >(.+?)</g; 
    var match; 
    while (match = re.exec(body)) { 
     matches[matches.length] = match[1]; 
    } 

    // Send back the array as JSON. 
    res.setHeader('content-type', 'application/json'); 
    res.end(JSON.stringify(matches)); 
    }); 
}); 

(обратите внимание, что я переименовал объект ответа на res, чтобы предотвратить его получение clobbered аргументом response обратного вызова request)

+0

Спасибо за удивительное объяснение! Изучение такого рода вещей может быть действительно запутанным, и, если кто-то вроде вас объяснит мне, это так приятно. – MarksCode

+0

@MarksCode вы очень желанны! = D – robertklep

0

Вместо трубопровода ответа, вы можете можете позвонить response.write() с каждым матчем, и response.end, когда вы закончили (с учетом каждого матча конкатенации правильно с предыдущим, так что общая реакция имеет все правильные разделители - Я не убедитесь, что в каждом матче), или вы можете отправить весь набор совпадений одним звонком response.end(). Что вы делаете, зависит немного от того, сколько матчей вы ожидаете.

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