javascript - Javascript 中的 Google Cloud Function 在函数完成之前完成

标签 javascript rest api google-bigquery google-cloud-functions

为了解释我的用例,我有一个 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/

相关文章:

javascript - AngularJS Web App 缺少 CORS header 'Access-Control-Allow-Origin'

python - Docker 上的 Flask 应用程序 : Max retries exceeded with URL

javascript - 尝试从 Chrome 扩展程序与 Google Contacts API 交互时出现 "No ' Access-Control-Allow-Origin ' header is present"

java - 尝试将api中的数据获取到JSON时在JSONArray上使用NullPointer

javascript - Windows 8 Metro 和谷歌分析

javascript - 在不重新加载页面的情况下从 Node/Express 向浏览器发送确认警报

javascript - 如何创建基于网络服务的计时器?

facebook - 从 Facebook Graph API/用户获取 "real"配置文件 URL

Heroku 应用程序的 API 子域,可能吗?

javascript - 增强javascript以更快地执行