![](/img/trans.png)
[英]Node.JS Airtable - Await doesn't wait for promise to be resolved
[英]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.