javascript - Firebase 云函数中的异步/等待说错误表达式的类型为“void”
问题描述
我正在尝试在我的 firebase 函数中使用 async/await,但出现错误。我已将该函数标记为异步,但是当我尝试在其中使用 await 时出现错误:Expression has type void
。将其作为声明放在自己的行中。
我认为这很奇怪,因为我认为每个 await 函数调用都已经在自己的行中作为语句。所以,我不确定该怎么做。任何帮助,将不胜感激。
为清楚起见,我正在向 Cheerio 网络抓取库发出请求,然后尝试在每个循环期间使用 .each 方法进行两个异步函数调用。
export const helloWorld = functions.https.onRequest((req, response) => {
const options = {
uri: 'https://www.cbssports.com/nba/scoreboard/',
transform: function (body) {
return cheerio.load(body);
}
};
request(options)
.then(($) => {
$('.live-update').each((i, element) => {
const homeTeamAbbr = $(element).find('tbody').children('tr').eq(0).find('a').html().split("alt/").pop().split('.svg')[0];
const awayTeamAbbr = $(element).find('tbody').children('tr').eq(1).find('a').html().split("alt/").pop().split('.svg')[0];
const homeTeam = $(element).find('tbody').children('tr').eq(0).find('a.team').text().trim();
const awayTeam = $(element).find('tbody').children('tr').eq(1).find('a.team').text().trim();
let homeTeamStatsURL = $(element).find('tbody').children('tr').eq(0).find('td').html();
let awayTeamStatsURL = $(element).find('tbody').children('tr').eq(1).find('td').html();
const gameTime = $(element).find('.pregame-date').text().trim();
homeTeamStatsURL = homeTeamStatsURL.match(/href="([^"]*)/)[1] + "roster";
awayTeamStatsURL = awayTeamStatsURL.match(/href="([^"]*)/)[1] + "roster";
const matchupString = awayTeamAbbr + "@" + homeTeamAbbr;
const URLString = "NBA_" + urlDate + "_" + matchupString;
// var docRef = database.collection('NBASchedule').doc("UpcommingSchedule");
// var boxScoreURL = "www.cbssports.com/nba/gametracker/boxscore/" + URLString;
// var setAda = docRef.set({[URLString]:{
// homeTeam: homeTeam,
// awayTeam: awayTeam,
// date: gameTime,
// homeTeamAbbr: homeTeamAbbr,
// awayTeamAbbr: awayTeamAbbr,
// homeTeamStatsURL: homeTeamStatsURL,
// awayTeamStatsURL: awayTeamStatsURL,
// boxScoreURL: boxScoreURL
// }}, { merge: true });
getTeamPlayers(homeTeamStatsURL, matchupString);
getTeamPlayers(awayTeamStatsURL, matchupString);
console.log("retrieved schedule for "+ matchupString + " on " + urlDate)
});
response.send("retrieved schedule");
})
.catch(function (err) {
console.log("error " + err);
});
});
我正在调用的函数只是发出另一个请求,然后我试图记录一些数据。
function getTeamPlayers(playerStatsURL, matchupString) {
const options = {
uri: playerStatsURL,
transform: function (body) {
return cheerio.load(body);
}
};
console.log(playerStatsURL + " stats url");
request(options)
.then(($) => {
console.log('inside cheerio')
$('tbody').children('tr').each(function(i, element){
const playerName = $(element).children('td').eq(1).children('span').eq(1).find('a').text().trim();
const injury = $(element).children('td').eq(1).children('span').eq(1).children('.icon-moon-injury').text().trim();
const news = $(element).children('td').eq(1).children('span').eq(1).children('.icon-moon-news').text().trim();
const playerUrl = $(element).children('td').eq(1).children('span').eq(1).find('a').attr('href');
const playerLogsUrl = "https://www.cbssports.com" + playerUrl.replace('playerpage', 'player/gamelogs/2018');
console.log(playerName + ": Inj: " + injury + " News: " + news);
// database.collection('NBAPlayers').add({[playerName]:{
// '01 playerName': playerName,
// '03 playerLogsUrl': playerLogsUrl,
// '04 inj': injury,
// '05 news': news
// }})
// .then(docRef => {
// console.log("ID " + docRef.id);
// //getPlayerLogs(playerLogsUrl, playerName, docRef.id);
// })
// .catch(error => console.error("Error adding document: ", error));
});
});
}
解决方案
以防有人追上来。正如 Ron 之前所说,async/await
如果第二次调用不需要第一次的值,则不应在传统的 for 循环中使用,因为这会增加代码的运行时间。
此外,您不能async/await
在 aforEach=>
或map=>
循环内使用,因为它不会停止并等待 promise 解决。
最有效的方法是使用Promise.all([])
. 在这里,我留下了一个很棒的 youtube 视频,其中解释async/await
和承诺 => https://www.youtube.com/watch?v=vn3tm0quoqE&t=6s
至于 DarkHorse 评论中的一个问题:
但我想要的只是让 getTeamPlayers() 执行并写入数据库,所以我不知道为什么我需要返回任何东西。
在 Firebase 函数中,所有函数都需要在最终响应之前返回一些内容。
例如在本例中,他创建了一个 http 函数。在他结束功能之前,response.send("retrieved schedule");
您需要完成触发的每个功能。由于 Firebase Functions 将在 final 之后清理response
,擦除并停止它仍在运行的任何内容。因此,任何尚未完成的功能都将在完成其工作之前被杀死。
返回 Promise 是 Firebase Functions 知道所有执行何时完成并可以清理的方式。
跳它有帮助:)
推荐阅读
- firebase - Firebase 存储 API 触发两次
- javascript - 如何在 Gatsby 插件中使用 React 组件?
- javascript - 没有从机器人模拟器获取数据到 blob 存储?
- gatsby - 从 Headless CMS(如 Strapi)在 Gatsby-Config.JS 中编辑站点元数据
- amazon-web-services - 无服务器步骤功能插件中指的是哪些活动部分?
- angular - 如何根据角度的html页面中的特殊字符过滤文件名?
- postgresql - ST_AsMVT 缓冲区在 PostGIS 3.0.1 开发中不起作用
- python - 创建 int64 结构的 int8 scipy 稀疏矩阵创建错误?
- ios - Flutter 在启动 iOS 应用程序时显示黑屏
- elasticsearch - 使用 logstash 从弹性搜索中删除数据或文档