为了解释我的用例,我有一个 GCP 计算引擎,运行一个内部构建的应用程序,并支持 RESTful API。我想做的是读取 RESTful API 来检查应用程序中的记录是否有任何更新。
如果有新记录,我想将其添加到用于在 Data Studio 中构建报告的 BigQUery 表中。
我遇到的问题是,该函数在 BigQuery 中的插入完成之前完成。我添加了 async,await 我似乎没有找到适合我的这项工作的正确公式,因此我正在向社区寻求输入。我很感激我能得到的任何建议。这是我的代码 ` '使用严格';
// Request Data From A URL
var axios = require('axios');
var https = require('https');
// Var Firebase Functions
var functions = require('firebase-functions');
const admin = require('firebase-admin');
// Initalise App
admin.initializeApp;
// Setting Timeout in Seconds - default is 1 second
// The maximum value for timeoutSeconds is 540, or 9 minutes. Valid values for memory are:
// 128MB, 256MB, 512MB, 1GB, 2GB
const runtimeOpts = {
timeoutSeconds: 300,
memory: '512MB'
}
exports.getEmilyNoonreporttoBigQuery = functions
.runWith(runtimeOpts)
.region('europe-west1')
.https.onRequest(async(req, res) => {
try {
// Imports the Google Cloud client library
const {BigQuery} = require('@google-cloud/bigquery');
// Create a client
const bigquery = new BigQuery();
//Make use of a dataset
const dataset = bigquery.dataset('noonreport');
//Make use of a table
const table = dataset.table('noonreport');
// The API Key
let apikey = 'API-KEY';
// Table to get data from
var apitable = 'noon_report';
// From were the data comes
var shipid = '1';
// Get the current date
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
today = yyyy + '-' + mm + '-' + dd;
var url = 'https://emily.apps.gl3/api/' + shipid + '/' + apitable + '?apikey=' + apikey + '&syncdate=' + today;
console.log('today', today);
console.log('url', url);
// At request level
const agent = new https.Agent({
rejectUnauthorized: false
});
// axios.get(url)
axios.get(url, { httpsAgent: agent })
.then(resp => {
try {
console.log("Response " + resp);
for(let artno in resp.data.noon_report) {
// Create the BigQuery Row
var row = {
ship: resp.data.noon_report[artno].noon_report.ship,
local_time: resp.data.noon_report[artno].noon_report.local_time || resp.data.noon_report[artno].noon_report.report_date,
status: resp.data.noon_report[artno].noon_report.status,
location: resp.data.noon_report[artno].noon_report.location,
course: resp.data.noon_report[artno].noon_report.course,
next_port: resp.data.noon_report[artno].noon_report.next_port,
ETD: resp.data.noon_report[artno].noon_report.ETD,
ETA: resp.data.noon_report[artno].noon_report.ETA,
distance_made: resp.data.noon_report[artno].noon_report.distance_made,
stoppage: resp.data.noon_report[artno].noon_report.stoppage,
avg_speed: resp.data.noon_report[artno].noon_report.avg_speed,
mgo_rob: resp.data.noon_report[artno].noon_report.mgo_rob,
mgo_consumed: resp.data.noon_report[artno].noon_report.mgo_consumed,
mgo_received: resp.data.noon_report[artno].noon_report.mgo_received,
fw_rob: resp.data.noon_report[artno].noon_report.fw_rob,
fw_consumed: resp.data.noon_report[artno].noon_report.fw_consumed,
fw_produced: resp.data.noon_report[artno].noon_report.fw_produced,
fw_received: resp.data.noon_report[artno].noon_report.fw_received,
underway_hours: resp.data.noon_report[artno].noon_report.underway_hours,
me_rh: resp.data.noon_report[artno].noon_report.me_rh,
heli_flight_hours: resp.data.noon_report[artno].noon_report.heli_flight_hours,
heli_fuel_consumed: resp.data.noon_report[artno].noon_report.heli_fuel_consumed,
heli_fuel_rob: resp.data.noon_report[artno].noon_report.heli_fuel_rob,
name_of_pilot: resp.data.noon_report[artno].noon_report.name_of_pilot,
nature_of_flight: resp.data.noon_report[artno].noon_report.nature_of_flight,
wind_direction: resp.data.noon_report[artno].noon_report.wind_direction,
wind_force: resp.data.noon_report[artno].noon_report.wind_force,
sea_state: resp.data.noon_report[artno].noon_report.sea_state,
weather: resp.data.noon_report[artno].noon_report.weather,
visibility: resp.data.noon_report[artno].noon_report.visibility,
barometer: resp.data.noon_report[artno].noon_report.barometer,
air_temp: resp.data.noon_report[artno].noon_report.air_temp,
remarks: resp.data.noon_report[artno].noon_report.remarks,
cur_timestamp: resp.data.noon_report[artno].noon_report.cur_timestamp,
cancelled: resp.data.noon_report[artno].noon_report.cancelled,
arrivaldep: resp.data.noon_report[artno].noon_report.arrivaldep,
shorepw: resp.data.noon_report[artno].noon_report.shorepw,
lo_rob: resp.data.noon_report[artno].noon_report.lo_rob,
lo_consumed: resp.data.noon_report[artno].noon_report.lo_consumed,
petrol_rob: resp.data.noon_report[artno].noon_report.petrol_rob,
petrol_consumed: resp.data.noon_report[artno].noon_report.petrol_consumed,
heli_fuel_received: resp.data.noon_report[artno].noon_report.heli_fuel_received,
petrol_received: resp.data.noon_report[artno].noon_report.petrol_received,
lo_received: resp.data.noon_report[artno].noon_report.lo_received,
campaign: resp.data.noon_report[artno].noon_report.campaign,
projectLeader: resp.data.noon_report[artno].noon_report.projectLeader,
visitorsOpen: resp.data.noon_report[artno].noon_report.visitorsOpen,
fundsOpen: resp.data.noon_report[artno].noon_report.fundsOpen,
vipsOpen: resp.data.noon_report[artno].noon_report.vipsOpen,
pressOpen: resp.data.noon_report[artno].noon_report.pressOpen,
volsOpen: resp.data.noon_report[artno].noon_report.volsOpen,
officeOpen: resp.data.noon_report[artno].noon_report.officeOpen,
clockChange: resp.data.noon_report[artno].noon_report.clockChange,
operPrepared: resp.data.noon_report[artno].noon_report.operPrepared,
techPrepared: resp.data.noon_report[artno].noon_report.techPrepared,
port_of_call: resp.data.noon_report[artno].noon_report.port_of_call|| "No Author Defined",
time_zone: resp.data.noon_report[artno].noon_report.time_zone,
report_date: resp.data.noon_report[artno].noon_report.report_date,
report_by: resp.data.noon_report[artno].noon_report.report_by,
berth_anchor_hours: resp.data.noon_report[artno].noon_report.berth_anchor_hours,
ship_activity: resp.data.noon_report[artno].noon_report.ship_activity,
uuid: resp.data.noon_report[artno].noon_report.uuid,
is_submit: resp.data.noon_report[artno].noon_report.is_submit,
helicopter_used: resp.data.noon_report[artno].noon_report.helicopter_used,
position_lat: resp.data.noon_report[artno].noon_report.position_lat,
position_lon: resp.data.noon_report[artno].noon_report.position_lon,
me1_distance: resp.data.noon_report[artno].noon_report.me1_distance,
me1_uw_hours: resp.data.noon_report[artno].noon_report.me1_uw_hours,
me2_distance: resp.data.noon_report[artno].noon_report.me2_distance,
me2_uw_hours: resp.data.noon_report[artno].noon_report.me2_uw_hours,
me1_2_distance: resp.data.noon_report[artno].noon_report.me1_2_distance,
me1_2_uw_hours: resp.data.noon_report[artno].noon_report.me1_2_uw_hours,
edrive_distance: resp.data.noon_report[artno].noon_report.edrive_distance,
edrive_uw_hours: resp.data.noon_report[artno].noon_report.edrive_uw_hours,
sail_distance: resp.data.noon_report[artno].noon_report.sail_distance,
sail_uw_hours: resp.data.noon_report[artno].noon_report.sail_uw_hours,
e_motorsail_distance: resp.data.noon_report[artno].noon_report.e_motorsail_distance,
e_motorsail_uw_hours: resp.data.noon_report[artno].noon_report.e_motorsail_uw_hours,
me_motorsail_distance: resp.data.noon_report[artno].noon_report.me_motorsail_distance,
me_motorsail_uw_hours: resp.data.noon_report[artno].noon_report.me_motorsail_uw_hours,
motoring_edrive_distance: resp.data.noon_report[artno].noon_report.motoring_edrive_distance,
motoring_edrive_uw_hours: resp.data.noon_report[artno].noon_report.motoring_edrive_uw_hours,
drifting_hours: resp.data.noon_report[artno].noon_report.drifting_hours,
country: resp.data.noon_report[artno].noon_report.author
};
console.log("ROW TO INSERT " + JSON.stringify(row));
insertBigQuery(row, table);
}
console.log("For Loop end");
res.status(200).send("OK");
}
catch (error) {
// Handle the error
console.log(error);
response.status(500).send(error);
}
})
}
catch (error) {
// Handle the error
console.log(error);
response.status(500).send(error);
}
//This Query inserts data after charges completed
async function insertBigQuery(row, table){
return await table.insert(row, function(err, apiResponse) {
//console.log('Insert', apiResponse);
if (!err) {
console.log("[BIGQUERY] - Saved.");
} else {
console.error(`error table.insert: ${JSON.stringify(err)}`)
// To finish http function return value
}
});
}
});
`
我有一个 for 循环来解压 RESTFul API 数据并构建一行以插入 BigQuery。我使用云调度程序通过 HTTP 触发器来触发此函数。
我使用的 URL 用于内部应用程序,因此在外部不可用。我获取数据并解压数据,该函数在数据插入 BigQuery 之前完成。
我尝试在调用 BigQuery 插入函数的行中添加等待,但没有成功。
await insertBigQuery(row, table);
没有成功,寻求帮助。
最佳答案
我认为我看到了几个问题。如果我们查看名为 insert
的 BigQuery 表对象 API,我们会发现它返回一个 Promise。伟大的。我们还看到它有一个可选的回调函数。我不确定您是否应该同时使用两者。您要么说结果将是一个随后将得到解决的 promise ,要么您说结果将通过回调告诉您。我不确定双方都会满意。我建议只使用 Promise。
但是,我认为更大的问题在于这个逻辑:
async function insertBigQuery(row, table){
return await table.insert(row, function(err, apiResponse) {
//console.log('Insert', apiResponse);
if (!err) {
console.log("[BIGQUERY] - Saved.");
} else {
console.error(`error table.insert: ${JSON.stringify(err)}`)
// To finish http function return value
}
});
}
把这个记下来......你有:
async function funcName() {
return await asyncFuncCall();
}
我想这可能是你的问题。通过在函数 (funcName
) 中添加 async
前缀,您可以声明该函数将返回一个 Promise
并且调用者不会阻塞等待返回,但调用者本身会收到一个 promise 。
我偷偷地怀疑你真正想要的是:
async function funcName() {
return asyncFuncCall();
}
然后在您想要调用 funcName() 的位置:
let finalResult = await funcName();
或
funcName().then((finalResult) => { ... logic ... });
关于javascript - Javascript 中的 Google Cloud Function 在函数完成之前完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58718352/