Node.js在另一个方法完成后调用一个方法 [英] Node.js Call a method after another method is completed

查看:60
本文介绍了Node.js在另一个方法完成后调用一个方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在"app.get('/news/api/:newsName',function(req,res)".

I would like to call my "app.get('/news/news-desc', (req, res)" method after "app.get('/news/api/:newsName', function(req, res)" is completed.

这是我的代码:

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.

As you can see, the first method calls the "newsapi.org" and gets 10 articles. Then it would only extract the urls of those articles and push them into articleUrlArray.

将网址推入articleUrlArray之后,它看起来像这样:

After the urls have been pushed into the articleUrlArray, it would look like this:

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做自己的事情.

Then the second method, would use the filled up articleUrlArray to do its own thing.

但是,目前,对于我的代码,第二个方法会在articleUrlArray填满之前先运行.

However, currently for my code, the second method runs first before the articleUrlArray has been filled up.

我想在第一种方法完成并且articleUrlArray已填满网址之后运行第二种方法.

I would like to run the second method after the first method completes and the articleUrlArray has been filled up with urls.

您能帮我吗?

推荐答案

如果需要,您可以将第一条路线的核心逻辑分离到一个函数中,然后在两个地方重新使用它.但是,您仍然需要向GET'/news/news-desc'端点提供newsName参数.

You can separate the core logic of the first route to a function and re-use it in both places, if you please. however you still need to provide newsName parameter to GET '/news/news-desc' endpoint.

您的代码示例.

    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)))
        })
    })

这篇关于Node.js在另一个方法完成后调用一个方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆