Поэтому мне интересно, возможно ли то, что я пытаюсь сделать, или мне нужно немного реструктурировать свой код. Прямо сейчас у меня есть цепочка обещаний с некоторыми различными функциями. Первый получает URL-адреса запросов, которые мне нужны, затем второй отображает URL-адреса и возвращает запрос для каждого из них. Я жду этих обещаний, а затем использую .reduce, чтобы создать массив из обещаний.
Однако я понял, что мне нужно передать некоторые дополнительные данные из первой функции (откуда я получаю данные расписания) на каждую итерацию .reduce () во второй функции. Затем я передам его в playerConstructor и использую его на моем объекте player.
import * as cheerio from 'cheerio';
import * as request from "request-promise-native";
exports.handler = function(req, res, database) {
const keys = require('./keys');
const constructors = require('./model/constructors')
const scheduleRef = database().collection(keys.nbaSchedule);
const nbaDraftRef = database().collection(keys.nbaDraft);
//deletePlayers
nbaDraftRef.get()
.then(getTeamUrls)
.then(readPlayers)
.then(writePlayers)
.catch(err => console.log("error writing schedule: " + err));
function getTeamUrls(scheduleSnapshot) {
const teamUrls = [];
scheduleSnapshot.docs.forEach((doc) => {
teamUrls.push(doc.data().homeTeamStatsURL, doc.data().awayTeamStatsURL)
//const scheduleGame = doc.data()
//const gameTime = scheduleGame.gameTime;
// const scheduleUrl = scheduleGame.urlString
// const gameUrlArray = scheduleUrl.split("_");
// const gameUrl = gameUrlArray[2];
// teamUrls.push({
// url: scheduleGame.homeTeamStatsURL,
// abbr: scheduleGame.homeTeamAbbr,
// gameTime: gameTime,
// gameUrl: gameUrl
// });
// teamUrls.push({
// url: scheduleGame.awayTeamStatsURL,
// abbr: scheduleGame.awayTeamAbbr,
// gameTime: gameTime
// gameUrl: gameUrl
// })
});
return teamUrls;
}
async function readPlayers(teamUrls) {
const playerPromises = teamUrls.map((teamUrl, i) => {
const options = {
gzip: true,
uri: teamUrl,
Connection: 'keep-alive',
transform: function(body) {
return cheerio.load(body);
}
};
return request(options)
});
const players = await Promise.all(playerPromises);
return players.reduce((allPlayers: any, $: any) => {
$('tbody').children('tr').each(function(j, element) {
const playerHtml = $(element)
allPlayers.push(constructors.playerConstructor(playerHtml));
});
return allPlayers;
}, [])
}
function writePlayers(allPlayers) {
allPlayers.forEach(player => {
nbaDraftRef.doc(player.playerDBRef)
.set(player)
.catch(error =>
console.error("Error adding document: ", error + " : " + player.playerName)
);
});
res.send("finished");
}
};
Я действительно понятия не имею, как выполнить sh, за исключением, может быть, совершенно другого подхода к структуре кода. ,
Я вижу, что вы можете передать некоторые дополнительные данные в функцию карты следующим образом:
array.filter(function(elem, index, array) {
//...
}, additionalArgs);
И я знаю, что вы можете вернуть несколько объектов одновременно в javascript, так что возможно playerPromises может выглядеть примерно так (передавая дополнительные данные расписания и возвращая их)
const playerPromises = teamUrls.map((teamUrl, i) => {
const options = {
gzip: true,
uri: teamUrl,
Connection: 'keep-alive',
transform: function(body) {
return cheerio.load(body);
}
};
return request(options), additionalScheduleData
}, additionalScheduleData);
Но не похоже, что вы можете сделать то же самое с помощью Reduce. На самом деле не уверен, хотя. Кто-нибудь?