web-dev-qa-db-ja.com

Request-Promiseを使用した非同期/待機が未定義を返す

2つのファイルがあります。以下のserver.jsとscrape.jsは、現在のコードスニペットです。

server.js:

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

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

start();

と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
};

したがって、server.jsを起動すると、undefinedをconsole.log(response)に返します。実際にプッシュした配列を返したい場合、どこが間違っているのかわかりますか?

9
razki

return関数から何かをasyncする必要があります(then内での戻りはメイン関数から戻りません)。約束またはあなたがawait- edしたもの。

また、go変数を宣言して、グローバルスペースにリークしないようにしてください。

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

async関数を使用しているため、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);
  }
};
15

あなたのgo関数は値を返さないと思います。

request(options).then(...)を呼び出していますが、その約束から続くものがgoによって返されることはありません。 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);
    });
};
2
Gershom Maes