我编写了一个程序来提取链接以分三步下载照片:
我正在尝试将步骤2重构为异步功能。 有没有简单的方法可以将第二步重构为一个函数,以使代码更具可读性?
理想情况下,我想检索所有链接,然后才开始下载。
const axios = require("axios");
const cheerio = require("cheerio");
const url = "https://www.website.com";
const persons = [];
async function getPersons() {
await axios.get(url).then(response => {
const html = response.data;
const $ = cheerio.load(html);
const personList = $(".bio-btn");
console.log(personList.length);
personList.each(function() {
const link_raw = $(this).attr("href");
const link = url + link_raw;
const name = link_raw.replace("/bio/", "");
person.push({
name,
link
});
});
});
}
getPersons().then(function() {
persons.forEach(async function(person) {
var personLink = person.link;
await axios.get(personLink).then(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $(".ratio-4-3");
snapshots.each(function() {
const pic = $(this).attr("style");
if (pic != undefined && pic.includes("biopicture")) {
var bioPhoto = s[1];
}
});
});
});
});
答案 0 :(得分:2)
随着您最终提出串行请求,您几乎不会从异步中获得很多好处。我会这样写(未经测试):
async function getPersons() {
const response = await axios.get(url);
const html = response.data;
const $ = cheerio.load(html);
const personList = $('.bio-btn');
const persons = [];
personList.each(function() {
const link_raw = $(this).attr('href');
const link = url + link_raw;
const name = link_raw.replace("/bio/", "");
persons.push({
name,
link,
});
});
return persons;
};
async function getSnapshots() {
const persons = await getPersons();
const linkPromises = persons.map(person => axios.get(person.link));
const linkResponses = await Promise.all(linkPromises);
linkResults.forEach(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $(".ratio-4-3");
// ...
});
}
答案 1 :(得分:1)
我会这样重构它。删除匿名函数上的.then()
方法和关键字function
使代码看起来更简洁。
使用Promise.all()
使您可以异步开始所有下载,这可能比逐个下载映像更好。
const axios = require('axios');
const cheerio = require('cheerio');
const url = 'https://www.website.com';
async function getPersons() {
const response = await axios.get(url);
return extractPersonList(response);
}
// Step 1
function extractPersonList(response) {
const persons = [];
const html = response.data;
const $ = cheerio.load(html);
const personList = $('.bio-btn');
console.log(personList.length);
personList.each(() => {
const link_raw = $(this).attr('href');
const link = url + link_raw;
const name = link_raw.replace('/bio/', '');
persons.push({
name,
link
});
});
return persons;
}
async function getPhotos() {
const persons = await getPersons();
const promisies = persons.map(p => axios.get(p.link));
// Step 2
const responses = await Promise.all(promisies);
// Step 3
responses.forEach(response => {
const html = response.data;
const $ = cheerio.load(html);
const snapshots = $('.ratio-4-3');
snapshots.each(() => {
const pic = $(this).attr('style');
if (pic && pic.includes('biopicture')) {
var bioPhoto = s[1];
}
});
});
}
// Call getPhotos to start the process
getPhotos();