Я создаю веб-скребок и отправляю несколько HTTP-запросов из облачной функции, используя обещания. Проблема в том, что я не уверен, где включить response.send ().
Моя функция getList () выполняет все запросы в асинхронном / ожидающем стиле, и я попытался поместить response.send в блок .then, как показано ниже.
getList().then((result)=>{
response.send("got current logs " + result);
}).catch(async (err) => {
console.log(err);
})
Я думал, что поскольку getList () возвращает обещание, которое оно выполнит, а затем, когда оно закончится, оно вызовет response.send (), и все будет работать нормально, но вместо этого он никогда не будет вызван. Весь код успешно записывается в БД, но затем облачная функция заканчивается тайм-аутом.
Я тоже пытался использовать promise.all (), но не уверен, что на правильном пути.
const requestPromise = getList()
Promise.all(requestPromise).then =>
response.send()
Но это тоже не работает. Response.send () никогда не вызывается. Я перепробовал много вещей, которые нашел в Интернете и на SO, но еще не разобрался в моей проблеме.
Я действительно думал, что поскольку getList () полностью структурирован с использованием async / await, я могу просто вызвать его сразу после функции, и она будет работать следующим образом.
getList()
response.send()
Но в этом случае getList () вообще не выполняется, поэтому я думаю, что res.send () вызывается до того, как getList () сможет завершиться.
Очевидно, я все еще новичок в цепочке обещаний и пытаюсь узнать, что происходит. Моя обработка ошибок тоже не самая лучшая, но вот полный код, над которым я работаю.
Если кто-нибудь сможет помочь, это будет оценено.
export const getCurrentLogs = functions.https.onRequest((req, response) => {
const Promise = require("bluebird");
const urlList = [];
const ref = scheduleRef
.get()
.then(async snapshot => {
//this loops through and gets the urls needed for the requests
snapshot.docs.forEach(doc => {
const scheduleGame = doc.data();
const boxScoreUrl = scheduleGame.boxScoreURL;
console.log("got url " + boxScoreUrl);
urlList.push("https://" + boxScoreUrl + "/");
});
//here I'm calling getList() right after the loop should finish, but I've also tried it in its own .then block among other things.
getList()
.then(result => {
response.send("got current logs " + result);
})
.catch(async err => {
console.log(err);
});
})
.catch(err => {
console.log("Error getting url", err);
});
async function getList() {
await Promise.map(urlList, (url, index, length) => {
return new Promise(
resolve => {
const options = {
uri: url,
Connection: "keep-alive",
transform: function(body) {
return cheerio.load(body);
}
};
console.log("got options for " + url + " / " + options);
request(options)
.then($ => {
console.log("made request for " + url);
const final = $(".center-content-container")
.find(".final-text")
.text()
.trim();
const time = $(".center-content-container")
.find(".time")
.text()
.trim();
console.log(final);
console.log(time);
$(".stats-rows")
.find("tbody")
.children("tr")
.not(".total-row")
.each(function(i, element) {
const playerPage = $(element)
.children("td")
.eq(0)
.find("a")
.attr("href");
const playerNameSplit = playerPage.split("/");
const playerDocRef = playerNameSplit[7];
console.log(playerDocRef);
return playersRef
.doc(playerDocRef)
.update({
currentLog: currentLog
})
.catch(error =>
console.error(
"Error adding document: ",
error + " : " + url
)
);
});
return;
})
.catch(async err => {
console.log(err);
return;
});
},
{
concurrency: 10
}
).catch(async err => {
console.log(err);
return;
});
}).catch(async err => {
console.log(err);
return;
});
}
});