【问题标题】:NodeJS - running function to load in variablesNodeJS - 运行函数以加载变量
【发布时间】:2017-07-01 09:58:57
【问题描述】:

我想知道如何让这个函数 (scrapData) 只运行一次,这样它就不会增加每个项目并一次加载。这是我的 CMD 中发生的事情的图像。我对JS不是很熟悉,所以我不太确定我做错了什么。

这是该命令的 sn-p 代码:

//latest articles command
if (message.content.startsWith(prefix + 'latest')) {

    //website url variables
    const website_domain = "https://hypebeast.com/";
    let website_path = args[0];
    let website_url = website_domain + website_path;

    //extra arguments variable
    let extra_arg = args.slice(1).join(" ");

    //if user inputs too many arguments
    if (extra_arg.length > 0) {
        message.reply('too many arguments! Please refer to `h.help` for correct usage.');

    } else {
        
        //opening url and loading in websites html
        function scrapData(website_url) {
            return rp(website_url)
                .then(body => {
                    var items = [],
                        $ = cheerio.load(body);
                    
                    //web scraping here
                    $('.post-box').each(function() {
                        var title = $(this).find($('.title h2 span')).first().text(),
                            caption = $(this).find($('.post-box-excerpt p')).first().text(),
                            article_url = $(this).find($('.col-hb-post-image a')).first().attr('href'),
                            thumbnail_long = $(this).find($('.thumbnail img')).first().attr('src');
                        
                        //adding title, caption, etc to list
                        items.push({title, caption, article_url, thumbnail_long});

                        //check items in console
                        console.log(items);
                    })
                    return items;
                })
        }

        //run webscraping function
        scrapData(website_url)
            .then(items => {
                //produce embed messages
                for (i = 0; i < items.length; i++) {
                    message.channel.send({
                        embed: {
                            color: config.embed_colour,
                            title: (i + 1 + ". " + items[i].title),
                            url: items[i].article_url,
                            description: items[i].caption,
                        }
                    })
                }
                message.channel.send("`SOURCE: " + website_url + "`");
                console.log('DONE!');
            })    
    }
    }

【问题讨论】:

  • 它可能比你想象的要好一些。每次将项目添加到“项目”数组时,都会打印该数组(console.log(items))。尝试打印一次数组。(例如在您的 //produce embed messages 评论之前)
  • 每次添加商品时都会请求网站吗?或者当它循环时? @ate_f
  • 就在它循环播放的时候。你在做 ` $('.post-box').each(function() {` 第一部分(` $('.post-box')) retrieves an array of items, and then .each` 循环它。你在做console.log(items) 每次迭代。

标签: javascript node.js function loops discord


【解决方案1】:

实际上,你的函数只运行了一次。 scrapData 仅从不在循环中的代码或 each 语句中调用一次(我假设代码的顶部 sn-p 是命令的开头)。要减少记录的控制台消息数量,请考虑将 console.log 调用移至 return 语句正上方的行。

作为对您的评论的直接回应,它仅在您致电rp(url) 时向网站请求一次信息。附加到它的then 主体包含一个循环,该循环作用于rp 的返回,但它已经完成了它的工作(这就是Promise 所保证的:在其他事情完成之后执行这个)。 cheerio 完全离线工作,并且它使用的任何数据在执行时都已经完全下载,它使用的函数的名称 (load) 在你的程序上下文中只是有点误导。 rp 获取正文,cheerio 只是在解析它。

【讨论】:

    最近更新 更多