带有ramda.js的爬虫(功能编程)

时间:2019-07-18 17:22:02

标签: functional-programming cheerio ramda.js

我正在尝试从TMDB网站抓取电影数据。我用纯JavaScript完成了代码,但是我想通过使用ramda.js将代码更改为函数式编程风格。

我在下面附加了我的代码。我想摆脱for循环(如果可能)并使用R.pipe函数。

(async () => {
  for (let i = 0; i < 1000; i++) {
    (() => {
      setTimeout(async () => {
        let year = startYr + Math.floor(i / 5);
        await request.get(path(year, i % 5 + 1), async (err, res, data) => {
          const $ = cheerio.load(data);
          let list = $('.results_poster_card .poster.card .info .flex a');
          _.forEach(list, (element, index) => {
            listJSON.push({
              MovieID: $(element).attr('id').replace('movie_', ''),
              Rank: (i % 5) * 20 + index + 1,
              Year: year
            });
          });
          if(i === 1000 - 1) {
            await pWriteFile(`${outputPath}/movieList.json`, JSON.stringify(listJSON, null, 2));
          }
        });
      }, 1000 * i);
    })(i);
  }
})().catch(error => console.log(error));

2 个答案:

答案 0 :(得分:0)

您可以使用Ramda range()函数替换循环。

https://ramdajs.com/docs/#range

R.range(0, 1000);

这将为您提供一个整数集合(您的i),您可以使用它(map()或任何需要的东西)。

答案 1 :(得分:0)

步骤:

1-在小函数中破坏代码
2-停止使用async await并使用promise.then(otherFunction)
3-使用promise时,您可以创建一个sleep函数,如下所示:const sleep = (time) => new Promise(resolve => setTimeout(resolve, time));

例如:

const process = index => sleep(1000)
   .then(() => makeRequest(index))
   .then(processData);

R.range(0, 1000)
   .reduce(
       (prev, actual) => prev.then(() => process(actual),
       Promise.resolve()
   ) // Sequential
   .then(printResult);

R.range(0, 1000)
   .map(process) // Parallel
   .then(printResult);