web-dev-qa-db-fra.com

Async/En attente avec Request-Promise renvoie Undefined

J'ai deux fichiers; server.js et scrape.js, les extraits de code ci-dessous sont les suivants.

server.js:

const scrape = require("./scrape");

async function start() {
    const response = await scrape.start();
    console.log(response);
}

start();

et scrape.js:

const cheerio = require("cheerio");
const request = require("request-promise");

go = async () => {

const options = {
  uri: "http://www.somewebsite.com/something",
  transform: function(body) {
    return cheerio.load(body);
  }
};

request(options)
  .then($ => {
    let scrapeTitleArray = [];
    $(".some-class-in-html").each(function(i, obj) {
      const data = $(this)
        .text()
        .trim();
      scrapeTitleArray.Push(data);
    });
    return scrapeTitleArray;
  })
  .catch(err => {
    console.log(err);
  });
};

module.exports = {
  start: go
};

Ainsi, lorsque je lance server.js, je renvoie undefined dans le fichier console.log (réponse), lorsque je souhaite réellement renvoyer le tableau sur lequel je me suis mis, pouvez-vous voir où je me trompe?

6
razki

Vous devez return quelque chose de votre fonction async (un retour dans a ne retourne pas de la fonction principale). Soit une promesse ou quelque chose que vous await- ed.

Assurez-vous également de déclarer votre variable go pour éviter toute fuite dans l'espace global. 

const go = async () => {

  const options = {
    uri: "http://www.somewebsite.com/something",
    transform: function(body) {
      return cheerio.load(body);
    }
  };

  return request(options)
    .then($ => {
      let scrapeTitleArray = [];
      $(".some-class-in-html").each(function(i, obj) {
        const data = $(this)
          .text()
          .trim();
        scrapeTitleArray.Push(data);
      });
      return scrapeTitleArray;
    })
    .catch(err => {
      console.log(err);
    });
};

Puisque vous utilisez une fonction async, vous pouvez également tirer parti de la syntaxe await.

const go = async () => {

  const options = {
    uri: "http://www.somewebsite.com/something",
    transform: function(body) {
      return cheerio.load(body);
    }
  };

  try {
    const $ = await request(options);
    $(".some-class-in-html").each(function(i, obj) {
      const data = $(this)
        .text()
        .trim();
      scrapeTitleArray.Push(data);
    });
    return scrapeTitleArray;
  }
  catch (err) {
    console.log(err);
  }
};
11
Alexander O'Mara

Je crois que votre fonction go ne renvoie aucune valeur.

Vous appelez request(options).then(...), mais la suite de cette promesse n'est jamais renvoyée par go. Je vous recommande d'ajouter une déclaration return:

go = async () => {

  const options = {
    uri: "http://www.somewebsite.com/something",
    transform: function(body) {
      return cheerio.load(body);
    }
  };

  // The only difference is that it says "return" here:
  return request(options)
    .then($ => {
      let scrapeTitleArray = [];
      $(".some-class-in-html").each(function(i, obj) {
        const data = $(this)
          .text()
          .trim();
        scrapeTitleArray.Push(data);
      });
      return scrapeTitleArray;
    })
    .catch(err => {
      console.log(err);
    });
};
0
Gershom Maes