簡體   English   中英

Promise 不等待函數 promise 被解析

[英]Promise doesn't wait for functions promise to be resolved

所以我一直在做一個刮板項目。

現在我已經實現了很多事情,但我一直堅持這一件事。

所以首先讓我解釋一下工作流程:scrapers在scraping scraping-service模塊中被調用,在這里我等待調用的函數的promise被解析。 數據在爬蟲中獲取,並傳遞給data_functions object,其中數據:合並、驗證並插入數據庫。

現在這里是代碼:

scraping-service

const olxScraper = require('./scrapers/olx-scraper');
const santScraper = require('./scrapers/sant-scraper');
//Calling scraper from where we want to get data about apartments
const data_functions = require('./data-functions/dataF');

let count = 1;

Promise.all([
  olxScraper.olxScraper(count),
  santScraper.santScraper(count),
]).then(() => data_functions.validateData(data_functions.mergedApartments));

所以這里我在等待這兩個函數的 promise,然后將合並的數據傳遞給data_functions中的validateData方法。

這是刮刀:

const axios = require('axios'); //npm package - promise based http client
const cheerio = require('cheerio'); //npm package - used for web-scraping in server-side implementations
const data_functions = require('../data-functions/dataF');

//olxScraper function which as paramater needs count which is sent in the scraping-service file.
exports.olxScraper = async (count) => {
  const url = `https://www.olx.ba/pretraga?vrsta=samoprodaja&kategorija=23&sort_order=desc&kanton=9&sacijenom=sacijenom&stranica=${count}`;
  //url where data is located at.
  const olxScrapedData = [];
  try {
    await load_url(url, olxScrapedData); //pasing the url and empty array
  } catch (error) {
    console.log(error);
  }
};

//Function that does loading URL part of the scraper, and starting of process for fetching raw data.
const load_url = async (url, olxScrapedData) => {
  await axios.get(url).then((response) => {
    const $ = cheerio.load(response.data);
    fetch_raw_html($).each((index, element) => {
      process_single_article($, index, element, olxScrapedData);
    });

    process_fetching_squaremeters(olxScrapedData); // if i place 
 //data_functions.mergeData(olxScrapedData); here it will work
  });
};

//Part where raw html data is fetched but in div that we want.
const fetch_raw_html = ($) => {
  return $('div[id="rezultatipretrage"] > div')
    .not('div[class="listitem artikal obicniArtikal  i index"]')
    .not('div[class="obicniArtikal"]');
};

//Here is all logic for getting data that we want, from the raw html.
const process_single_article = ($, index, element, olxScrapedData) => {
  $('span[class="prekrizenacijena"]').remove();
  const getLink = $(element).find('div[class="naslov"] > a').attr('href');
  const getDescription = $(element).find('div[class="naslov"] > a > p').text();
  const getPrice = $(element)
    .find('div[class="datum"] > span')
    .text()
    .replace(/\.| ?KM$/g, '')
    .replace(' ', '');
  const getPicture = $(element).find('div[class="slika"] > img').attr('src');
  //making array of objects with data that is scraped.
  olxScrapedData[index] = {
    id: getLink.substring(27, 35),
    link: getLink,
    description: getDescription,
    price: parseFloat(getPrice),
    picture: getPicture,
  };
};

//Square meters are needed to be fetched for every single article.
//This function loads up all links in the olxScrapedData array, and updating objects with square meters value for each apartment.
const process_fetching_squaremeters = (olxScrapedData) => {
  const fetchSquaremeters = Promise.all(
    olxScrapedData.map((item) => {
      return axios.get(item.link).then((response) => {
        const $ = cheerio.load(response.data);
        const getSquaremeters = $('div[class="df2  "]')
          .first()
          .text()
          .replace('m2', '')
          .replace(',', '.')
          .split('-')[0];
        item.squaremeters = Math.round(getSquaremeters);
        item.pricepersquaremeter = Math.round(
          parseFloat(item.price) / parseFloat(getSquaremeters)
        );
      });
    })
  );

  fetchSquaremeters.then(() => {
    data_functions.mergeData(olxScrapedData); //Sending final array to mergeData function.
    return olxScrapedData;
  });
};

現在,如果我console.log(olxScrapedData)fetchSquaremeters.then它將 output 刮掉公寓,但它不想調用 function data_functions.mergeData(olxScrapedData) 但是如果我在load_url中添加那個塊,它會觸發函數和數據被合並,但是沒有平方米的東西,我真的需要那個數據。

所以我的問題是,如何使這項工作? 我需要在其他地方打電話給 function 嗎?

我想要的只是將最后一個olxScrapedData發送到這個 function mergeData以便我來自不同刮板的 arrays 將合並為一個。

謝謝!

編輯:這也是其他刮板的外觀: https://jsfiddle.net/oh03mp8t/ 請注意,在這個刮板中沒有任何承諾。

嘗試添加: const process_fetching_squaremeters = async (olxScrapedData)...然后await fetchSquaremeters.then(..)

詹姆斯,在回答之前告訴你發生了什么。 您必須等待此 promise 解決,才能正確執行。 如果你沒有使用 async/await 和 promises 的經驗,我建議你看一些關於它們的課程,以真正了解這里發生了什么

您是否缺少承諾/異步語句中的返回/等待語句,尤其是當您的最后一條語句也是 promise 時?

否則,您可能只是要求稍后執行 promise,而不是返回結果並讓 $.all() 等待它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM