Node.js在另一个方法完成后调用方法

时间:2018-05-21 02:53:06

标签: javascript node.js reactjs express nodes

我想在“app.get('/ news / api /:newsName',function(req,)之后调用我的”app.get('/ news / news-desc',(req,res)“方法) res)“完成了。

这是我的代码:

let articleUrlArray = [];

app.get('/news/api/:newsName', function(req, res) {
  const API_KEY = 'example';

  let data = '';

  const techCrunchURL = `https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=${API_KEY}`

  switch(req.params.newsName) {
    case 'tech-crunch':
      request(techCrunchURL, function(err, response, html) {
    
        let formattedData = JSON.parse(response.body);

        for(let i = 0; i < formattedData.articles.length; i++) {
          articleUrlArray.push(formattedData.articles[i].url);
        }

        data = response.body;
        res.setHeader('Content-Type', 'application/json');
        res.send(data);
      });

      break;

    default:
      data = 'Please type in correct news source';
      break;
  }
})

const checkBody = res => (err, response, html) => {
    const $ = cheerio.load(html);
    const articleContent = $('.article-content').children('p')
    const bodyOne = articleContent.eq(0).text()
    const bodyTwo = articleContent.eq(1).text()
    const isExtensive = bodyOne.split(' ').length > 50
    res(isExtensive ? { bodyOne } : { bodyOne, bodyTwo })
}

const getArticle = article => new Promise(res => request(article, checkBody(res)))

app.get('/news/news-desc', (req, res) => {
    Promise.all(articleUrlArray.map(getArticle)).then(data => res.send(JSON.stringify(data)))
})

如您所见,第一种方法调用“newsapi.org”并获得10篇文章。然后它只会提取这些文章的网址并将它们推入articleUrlArray。

将url推入articleUrlArray后,它看起来像这样:

let articleUrlArray = [ 'https://techcrunch.com/2018/05/19/shared-housing-startups-are-taking-off/',
  'https://techcrunch.com/2018/05/19/shared-housing-startups-are-taking-off/',
  'https://techcrunch.com/2018/05/19/my-data-request-lists-guides-to-get-data-about-you/',
  'https://techcrunch.com/2018/05/19/siempos-new-app-will-break-your-smartphone-addiction/',
  'https://techcrunch.com/2018/05/19/la-belle-vie-wants-to-compete-with-amazon-prime-now-in-paris/',
  'https://techcrunch.com/2018/05/19/apple-started-paying-15-billion-european-tax-fine/',
  'https://techcrunch.com/2018/05/19/original-content-dear-white-people/',
  'https://techcrunch.com/2018/05/19/meet-the-judges-for-the-tc-startup-battlefield-europe-at-vivatech/',
  'https://techcrunch.com/2018/05/18/nasas-newest-planet-hunting-satellite-takes-a-stellar-first-test-image/',
  'https://techcrunch.com/video-article/turning-your-toys-into-robots-with-circuit-cubes/',
  'https://techcrunch.com/2018/05/18/does-googles-duplex-violate-two-party-consent-laws/' ];

它只会被网址填满。

然后第二种方法,将使用填充的articleUrlArray来做自己的事情。

但是,目前对于我的代码,第二种方法在填充articleUrlArray之前首先运行。

我想在第一个方法完成后运行第二个方法,并且使用url填充了articleUrlArray。

你能帮帮我吗?

2 个答案:

答案 0 :(得分:0)

如果您愿意,您可以将第一条路线的核心逻辑分离到一个功能并在两个地方重复使用。但是你仍然需要向GET'/ news / news-desc'端点提供newsName参数。

代码示例。

    let articleUrlArray = [];

    function getNewsNames(newsName, callback) {
        const API_KEY = 'example';
        let data = '';
        const techCrunchURL = `https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=${API_KEY}`

        switch (newsName) {
            case 'tech-crunch':
                request(techCrunchURL, function (err, response, html) {

                    let formattedData = JSON.parse(response.body);

                    for (let i = 0; i < formattedData.articles.length; i++) {
                        articleUrlArray.push(formattedData.articles[i].url);
                    }

                    data = response.body;
                    callback(null, data);
                });

                break;

            default:
                data = 'Please type in correct news source';
                callback('Error', data);
                break;
        }
    }

    app.get('/news/api/:newsName', function (req, res) {

        getNewsNames(req,params.newsName, (err, data) => {
            if (!err) {
                res.setHeader('Content-Type', 'application/json');
            }

            return res.send(data);
        })
    })

    const checkBody = res => (err, response, html) => {
        const $ = cheerio.load(html);
        const articleContent = $('.article-content').children('p')
        const bodyOne = articleContent.eq(0).text()
        const bodyTwo = articleContent.eq(1).text()
        const isExtensive = bodyOne.split(' ').length > 50
        res(isExtensive ? { bodyOne } : { bodyOne, bodyTwo })
    }

    const getArticle = article => new Promise(res => request(article, checkBody(res)))

    app.get('/news/news-desc/:newsName', (req, res) => {
        getNewsNames(req.params.newsName, (err, data) => {
            // by now, the articleUrlArray array will be filled
            Promise.all(articleUrlArray.map(getArticle)).then(data => res.send(JSON.stringify(data)))
        })
    })

答案 1 :(得分:0)

let articleUrlArray = [];
const addArticleUrl = url => articleUrlArray.push(url)

const checkBody = res => (err, response, html) => {
  const $ = cheerio.load(html);
  const articleContent = $('.article-content').children('p')
  const bodyOne = articleContent.eq(0).text()
  const bodyTwo = articleContent.eq(1).text()
  const isExtensive = bodyOne.split(' ').length > 50
  res(isExtensive ? { bodyOne } : { bodyOne, bodyTwo })
}

const getArticle = article => new Promise(res => request(article, checkBody(res)))

const newsDescMiddleware = app.get('/news/news-desc', (req, res) => {
  Promise.all(articleUrlArray.map(getArticle)).then(data => res.send(JSON.stringify(data)))
})

const techCrunch = res => url => request(url, (err, response, html) => {
  let formattedData = JSON.parse(response.body);
  formattedData.articles.forEach(article => addArticleUrl(article.url))
  res(response.body)
})

const getNewsByName = (newsName, url) => new Promise((res, reject) => ({
  'tech-crunch': techCrunch(res)(url)
}[newsName])) || reject()

const getNewsByNameMiddleware = (req, res) => {
  const API_KEY = 'example';
  const techCrunchURL = `https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=${API_KEY}`

  getNewsByName(req.params.newsName, url)
    .then(body => {
      res.setHeader('Content-Type', 'application/json');
      res.send(body)
    })
    .catch(() => res.send('Please type in correct news source'))
}

app.get('/news/api/:newsName', getNewsByNameMiddleware, newsDescMiddleware)

在这里,我为你制作了一些中间件。

我假设您不需要先前中间件的响应。

我喜欢按照职责分割代码并在功能上进行编写。