Javascript 试图从异步函数返回对象数组,数组返回未定义
我一直在研究刮板功能 现在关于这个应用程序:有两个刮刀,从两个页面上刮取关于公寓的数据。现在,当数据完成刮取后,它将被传递到Javascript 试图从异步函数返回对象数组,数组返回未定义,javascript,node.js,arrays,object,Javascript,Node.js,Arrays,Object,我一直在研究刮板功能 现在关于这个应用程序:有两个刮刀,从两个页面上刮取关于公寓的数据。现在,当数据完成刮取后,它将被传递到mergeData函数,其中的目标是将从刮取器传递的所有对象数组合并到一个包含所有刮取器对象的单个数组中,然后传递到插入函数,插入到数据库中 这是一个刮刀 const data_functions = require('../data-functions/data-functions'); const axios = require('axios'); //npm pack
mergeData
函数,其中的目标是将从刮取器传递的所有对象数组合并到一个包含所有刮取器对象的单个数组中,然后传递到插入函数,插入到数据库中
这是一个刮刀
const data_functions = require('../data-functions/data-functions');
const axios = require('axios'); //npm package - promise based http client
const cheerio = require('cheerio'); //npm package - used for web-scraping in server-side implementations
//santScaper function which as paramater needs count which is sent in the scraping-service file.
exports.santScraper = async (count) => {
const url = `https://www.sant.ba/pretraga/prodaja-1/tip-2/cijena_min-20000/stranica-${count}`;
const santScrapedData = [];
try {
load_url(url, santScrapedData);
} 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, santScrapedData) => {
await axios.get(url).then((response) => {
const $ = cheerio.load(response.data);
fetch_raw_html($).each((index, element) => {
process_single_article($, index, element, santScrapedData);
});
data_functions.mergeData(santScrapedData); <- here is data passed into the mergeData component
});
};
//Part where raw html data is fetched but in div that we want.
const fetch_raw_html = ($) => {
return $('div[class="col-xxs-12 col-xss-6 col-xs-6 col-sm-6 col-lg-4"]');
};
//Here is all logic for getting data that we want, from the raw html.
const process_single_article = ($, index, element, santScrapedData) => {
const getLink = $(element).find('a[class="re-image"]').attr('href');
const getDescription = $(element).find('a[class="title"]').text();
const getPrice = $(element)
.find('div[class="prices"] > h3[class="price"]')
.text()
.replace(/\.| ?KM$/g, '')
.replace(',', '.');
const getPicture = $(element).find('img').attr('data-original');
const getSquaremeters = $(element)
.find('span[class="infoCount"]')
.first()
.text()
.replace(',', '.')
.split('m')[0];
const pricepersquaremeter =
parseFloat(getPrice) / parseFloat(getSquaremeters);
santScrapedData[index] = {
id: getLink.substring(42, 46),
link: getLink,
description: getDescription,
price: Math.round(getPrice),
picture: getPicture,
squaremeters: Math.round(getSquaremeters),
pricepersquaremeter: Math.round(pricepersquaremeter),
};
};
现在返回[undefined]
,我希望在这里填充来自两个scraper的对象
现在我想要的是:一个刮板在数组中返回~9个对象,而第二个刮板在数组中返回~30个对象。现在,我希望将这两个数组合并到函数中,并作为一个数组与对象一起传递(因此mergedApartments.length
将为~39。我无法实现这一点,我尝试了许多其他问题的解决方案,但都没有成功
什么是正确的解决方案?谢谢!
//您的数据模块:
常量数据函数={
合并方:[],
合并数据(公寓){this.mergedApartments.push(…公寓)},
};
//Scrape mock:异步函数,返回数据数组
const load_url=()=>newpromise(resolve=>setTimeout(()=>resolve([1,2,3,4]),2000);
//刮刀1:
const=async()=>{
const data=await load_url();//想象一下,在创建数组之前,所有的抓取数据的操作。。
数据函数。合并数据(数据);
返回数据;
};
//刮刀2:
const anotherScraper=async()=>{
const data=await load_url();//想象一下,在创建数组之前,所有的抓取数据的操作。。
数据函数。合并数据(数据);
返回数据;
};
//调用两个刮片器,等待它们并在一个阵列中获取所有内容:
Promise.all([santScraper(),另一个Scraper()]))
.then(()=>console.log(data_functions.mergedApartments))
此.mergeData().then((result)=>console.log(result));
-此字符串在srcap函数之前调用(当您需要此模块时)。在此处添加未定义的值(空函数参数)到您的累积数组并将此数组发布到控制台。难怪您会看到[未定义]
。请在废弃函数完成后尝试发布控制台日志谢谢,这很有意义!那么,函数将如何准确地知道这些废弃函数是否完成了它们的工作呢?有很多选择,例如,您可以使用本机jsPromise.all
,或者计算回调调用,或者使用,或者使用像async ,bluebird
或deferred
等。非常感谢。我将探索bluebird
。此外,如果你能举一些已经做过类似我的例子的例子,或者你将如何处理这个问题,我将非常感谢。
let mergedApartments = [];
exports.mergeData = async (apartments) => {
//Fetching all apartments that are passed from scraper(s)
mergedApartments = mergedApartments.concat(apartments);
//Sending data for validation to the validation function
return mergedApartments;
};
this.mergeData().then((result) => console.log(result));