Метеор не ждет результата от функции, возвращает неопределенное

1

Я создаю небольшой веб-скребок, и я наткнулся на следующую проблему: моим приложениям нужно очистить разные части веб-сайта и поместить информацию в базу данных. Иногда это дает безумные результаты, такие как дублированные записи, или возвращает неопределенные из функции getPhoto(). Однако, если я вызываю эту функцию (и не запускаю остальную часть скрипта), она возвращает правильный результат!

У меня есть цикл for, который перебирает разные URL-адреса. Он направляется на каждый URL-адрес и сбрасывает следующую информацию: 1. название, 2.description, 3. внутренняя ссылка, 4. вызывает функцию, которая генерирует изображение в соответствии с заголовком (getPhoto (...)), 5. сохраняет результаты в БД. Все происходит на сервере (я использую задания Cron, без взаимодействия с клиентом)

 for (i = 0; i < AllLinks.length; i++) {  

  if (AllLinks[i] != undefined && AllLinks[i] != null && sepLink[2] == "www.fly4free.pl") {

    var t2 = {
      travelTitle: null,
      travelTitle2: null,
      travelTitle3: null,
      travelDescription: null,
      travelDescription2: null,
      travelDescription3: null,
      travelBuy: null,
      travelBuy2: null,
      travelImage: null
    };

    var TravelLink1 = AllLinks[i];

    result = HTTP.get(AllLinks[i], {});
    $ = cheerio.load(result.content);

    t2.travelTitle = $('.article__title').text();
    t2.travelDescription = $('.article__content').find('p').first().text();

    if ($("img[src$='//www.fly4free.pl/wp-content/uploads/2016/09/lotJm.png']").parent().attr('href') != null) {
      t2.travelBuy = $("img[src$='//www.fly4free.pl/wp-content/uploads/2016/09/lotJm.png']").parent().attr('href'); // Link to buy
    }

    if (t2.travelBuy) {
      if (t2.travelBuy.split('https://').pop().split('http://').pop() != null) {
        t2.travelBuy2 = t2.travelBuy.split('https://').pop().split('http://').pop(); // link ready for DB
      } else {
        t2.travelBuy2 = t2.travelBuy;
      }
    }        

    t2.travelTitle3 = convertCurrencyInText(t2.travelTitle, 'PLN');
    t2.travelDescription3 = convertCurrencyInText(t2.travelDescription, 'PLN');

    translate(t2.travelTitle3, {from: 'pl', to: 'en'}).then(res => {
      t2.travelTitle2 = res.text; // title for DB
      if (t2.travelTitle2) { t2.travelImage = getPhoto(t2.travelTitle2); }

      translate(t2.travelDescription3, {from: 'pl', to: 'en'}).then(response => {
        t2.travelDescription2 = response.text; // description for DB

        if (t2.travelDescription2 != null && t2.travelTitle2 != null && t2.travelBuy2 != null && TravelLink1 != null && t2.travelImage != null) {
          Links.insert({ title: t2.travelTitle2, description:t2.travelDescription2, image: t2.travelImage, buyLink:t2.travelBuy2, link: TravelLink1, datetime: new Date() });
        } 

      }).catch(err => {
        console.error(err);
      });

    }).catch(err => {
      console.error(err);
    });

  }

}

"AllLinks" содержит разные URL-адреса. У меня проблемы с очисткой этого URL: http://www.fly4free.pl/na-wakacje-do-toskanii-tanie-loty-do-pizy-z-gdanska-za-170-pln/

Функция getPhoto()

    function getPhoto(title) {

  var travelPlace = nlp(title).match('to *').out('text').replace('to','').trim();
  if (travelPlace) {var travelPlace2 = travelPlace.split(' '); } 
  if (travelPlace2) {var travelPlace3 = travelPlace2[0] + "+" + travelPlace2[1]; } 
  if (travelPlace3) {
    var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+travelPlace3+"&category=travel&orientation=horizontal";
    var images = (HTTP.get(URL, {}));

    if (images.data.totalHits > 0) {
      var imageLink = images.data.hits[0].webformatURL;
      return imageLink;

    } else if (images.data.totalHits == 0) {
      var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+travelPlace2[0]+"&category=travel&orientation=horizontal";
      var images = (HTTP.get(URL, {}));

      if (images.data.totalHits > 0) {
        var imageLink = images.data.hits[0].webformatURL;
        return imageLink;
      }

    }
  } else if (nlp(title).places().data().length > 0) {
    var result = nlp(title).places().data()[0].text.replace(/[^a-zA-Z ]/g, "").trim();
    var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+result+"&category=travel&orientation=horizontal";
    var images = (HTTP.get(URL, {}));

    if (images.data.totalHits > 0) {
      var imageLink = images.data.hits[0].webformatURL;
      return imageLink;
    }

  } else {
    var title2 = title.replace(/[^a-zA-Z ]/g, "").split(" ");
    if (title2) {
      for(i = 0; i < title2.length; i++) {

        if (cities[title2[i]] == 1) {

          var URL = "https://pixabay.com/api/?key="+API_KEY+"&q="+title2[i]+"&category=travel&orientation=horizontal";
          var images = (HTTP.get(URL, {}));

          if (images.data.totalHits > 0) {
            var imageLink = images.data.hits[0].webformatURL;
            return imageLink;
          }

        } else {

          var URL = "https://pixabay.com/api/?key="+API_KEY+"&q=travel&category=travel&orientation=horizontal";
          var images = (HTTP.get(URL, {}));

          if (images.data.totalHits > 0) {
            var imageLink = images.data.hits[0].webformatURL;
            return imageLink;
          }


        }
      }
    }  
  }

}

Я пытаюсь настроить консоль журнала результатов - иногда я получаю правильное изображение из getPhoto(), но неопределенная ссылка из t2.travelBuy, иногда наоборот. Можете ли вы сказать мне, что я делаю неправильно? Я видел, как некоторые люди используют обещания или асинхронные/ждущие функции по таким проблемам. Как вы думаете, это мне поможет? Как мне изменить свой код, чтобы очистить веб-сайт, не получив "undefined"?

"translate" происходит от пакета "google-translate-api"

Теги:
web-scraping
function
meteor
serverside-javascript

1 ответ

0

вы можете попробовать var new_func = Meteor.wrapAsync (ВАША ФУНКЦИЯ, КОТОРУЮ ИМЕЕТ ВЫЗОВ), а когда вы используете new_func(), он вернет результат, как вы ожидали бы от нормальной функции, а не ожидая обратного вызова

  • 0
    мои функции не имеют обратных вызовов. Как я мог изменить их?
  • 0
    у вас HTTP.get есть обратный вызов, но он может быть опущен на сервере, но чтобы получить ошибку, нужно вместо этого ее перехватить
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню