2017-07-01 5 views
0

Ich frage mich, wie würde ich gehen, um diese Funktion (scrapData) nur einmal ausführen, so dass es nicht jedes Element erhöht und gleichzeitig lädt. Hier ist ein Bild von dem, was in meinem CMD passiert. Ich bin mit JS nicht sehr vertraut, also bin ich mir nicht wirklich sicher, was ich falsch mache. enter image description hereNodeJS - laufende Funktion zum Laden von Variablen

Und hier ist ein Code-Snippet für diesen einen Befehl:

//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 scrapping 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 webscrapping 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!'); 
      })  
    } 
    } 
+0

Es geht wahrscheinlich etwas besser als Sie denken. Jedes Mal, wenn Sie ein Element zum Array "Elemente" hinzufügen, drucken Sie dieses Array (console.log (Elemente)). Versuchen Sie, das Array einmal auszudrucken (zum Beispiel kurz vor dem '// product embed messages' Kommentar) –

+0

Fordert es die Website jedes Mal auf, wenn ein Element hinzugefügt wird? oder wenn es loops? @ate_f – hsel

+0

Nur wenn es loops. Sie tun '$ ('. Post-box'). Jeder (function() {' der erste Teil ('$ ('. Postbox')') ruft ein Array von Elementen ab und dann '.each' Loops darüber. Sie machen 'console.log (items)' für jede Iteration. –

Antwort

0

Eigentlich , Ihre Funktion ist nur ein einziges Mal bereits ausgeführt. scrapData wird nur einmal aus Code nicht in einer Schleife oder each Anweisung aufgerufen (ich nehme an, die Spitze des Codeausschnitts ist der Anfang des Befehls). Um die Anzahl der protokollierten Konsolenmeldungen zu verringern, ziehen Sie in Betracht, den console.log-Anruf in die Zeile direkt über der return-Anweisung zu verschieben.

Als direkte Antwort auf Ihren Kommentar fordert es nur einmal Informationen von der Website, wenn Sie rp(url) anrufen. Der then Körper, der an das angeschlossen wird, enthält eine Schleife, die auf der Rückkehr von rp handelt, aber es hat bereits seine Arbeit beendet (das ist, was das Versprechen garantiert: führen Sie dieses aus, nachdem etwas anderes beendet wird). cheerio arbeitet vollständig offline und alle Daten, mit denen es arbeitet, sind bereits vollständig zum Zeitpunkt der Ausführung heruntergeladen, der Name der Funktion (load) ist einfach etwas irreführend im Kontext Ihres Programms. rp bekommt den Körper, cheerio ist einfach zu analysieren.

Verwandte Themen