2017-02-20 21 views
0

Я работаю над веб-скрепером Node.js с некоторым кодом, как показано ниже, и пытается ориентировать мой код функционально. Смотрите ниже:Лучший способ передать данные в виде ряда функций?

const Promise = require('bluebird'); 
const fetch = require('node-fetch'); 
const cheerio = require('cheerio'); 

const scrapeUri = uri => fetch(uri); // how should i pass the uri from here 
const fetchURIs = URIs => Promise.all(URIs.map(scrapeUri)); 
const getBodies = pages => Promise.all(pages.map(page => page.text())); 
const toSource = source => cheerio.load(source); 
const shouldScrape = ($) => { 
    const shouldIndex = $('meta[name="robots"]').attr('content'); 
    if (['noindex', 'nofollow'].indexOf(shouldIndex) !== -1) { 
    return false; 
    } 
    return true; 
}; 

const objectifyContent = ($) => { // to be accessed here 
    return { 
    meta: { 
     index_timestamp: new Date(), 
     title: $('title').html(), 
     // TODO: this will totally fail in some instances, need to pass uri from initial instance 
     uri: $('link[rel="canonical"]').attr('href'), 
     description: $('meta[name="description"]').attr('content'), 
    }, 
    }; 
}; 

В objectifyContent, что будет чистый способ доступа Ури из начального scrapeUri вместо того, чтобы пытаться получить URL-страницы путем доступа к канонической? Я знаю некоторые способы, которыми я мог бы установить переменную и наследовать ее до уровня, но мне было интересно, есть ли более чистый, более функциональный способ выполнения в этом в контексте Node.js.

Вызывающий будет выглядеть следующим образом: fetchUris(myUris).then(values => getBodies(values).then(sources => res.send(sources.map(toSource).filter(shouldScrape).map(objectifyContent));)

+0

Почему бы не просто добавить его в подпись 'objectifyContent'? Является ли эта подпись продиктованной какой-то структурой? Если нет, не можете ли вы просто сделать это '($, uri) => {...}' или '($) => (uri) => {...}'? (Или обратный порядок, в зависимости от вашего вкуса и который, скорее всего, изменится.) –

+0

Я думаю, вопрос в том, что эти функции используются в серии, где 'objectifyContent' находится в конце серии' map' и 'filter's. Как сохранить uri каждого массива для использования позже в серии? – LA1CH3

+0

Вы должны показать нам, что фактический код, в котором вы используете '.map()' и '.filter()', чтобы мы предложили лучший ответ в этом контексте. Возможно, то, что вы хотите накапливать, - это массив объектов с несколькими свойствами, а не просто фильтрация одного значения. Они могут хранить несколько фрагментов информации для каждого устройства. – jfriend00

ответ

0

Изменить этот scrapeUri передать URI через обещание, и изменить обработчик соответственно

const scrapeUri = uri => fetch(uri).then(
    webpage => [uri, webpage] 
) 
+0

Это, по сути, идея, с которой я пошел, за исключением того, что я использовал 'Promise.props' и использовал объекты, а не массивы. – LA1CH3