How to call a synchronous sub function from a Cloud Function

无人久伴 提交于 2021-02-10 07:59:06

问题


I'd like to run all of my functions synchronously. But if I execute something like the code below the response is sent back before the return value is assigned.

index.js

exports.cfTest = (req, res) => {
    try {
        result = columnCount(
         'project','dataset','table'
        );
        console.log('sending response');
        res.send('<OUTPUT>' + result + '</OUTPUT>');
    } catch (err) {
        res.status(500).send('<ERROR>' + err + '</ERROR>');     
    }
};

function columnCount(projectId, bqDataset, bqTable) {

    const BigQuery = require('@google-cloud/bigquery');
    const bigquery = new BigQuery({projectId: projectId});

    var result;

    bigquery
    .dataset(bqDataset)
    .table(bqTable)
    .get()
    .then(results => {
        result = results[1].schema.fields.length;   
    })
    .catch(err => {
        result = null;
    });

    console.log('returning ' + result);
    return result;
}

I.e the console output would be something like:

<OUTPUT>undefined</OUTPUT> 

and in the Stackdriver logs would show an execution order like this:

 2018-07-25 10:00:00 - Function execution started
 2018-07-25 10:00:01 - sending response
 2018-07-25 10:00:02 - Function execution took 2000 ms, finished with status code: 200
 2018-07-25 10:00:03 - returning 5

This is any elegant way to lock down execution into synchronous only behaviour?

Solution

The async/await approach suggested below by Alexandru works! Thanks Alexandru.

NB: But not with standard/GA Cloud Functions. You'll have to use the Google Cloud Functions Node.js v8 Beta.


回答1:


Yep, there is you can look at async/await

Your code will look something like this one in the end:

async function columnCount(projectId, bqDataset, bqTable) {
  const BigQuery = require('@google-cloud/bigquery');
  const bigquery = new BigQuery({ projectId: projectId });

  try {
    let results = await bigquery
      .dataset(bqDataset)
      .table(bqTable)
      .get();

    return results[1].schema.fields.length;
  } catch (err) {
    return null;
  }
}

And in the second one

exports.cfTest = async (req, res) => {
  try {
      result = await columnCount(
       'project','dataset','table'
      );
      console.log('sending response');
      res.send('<OUTPUT>' + result + '</OUTPUT>');
  } catch (err) {
      res.status(500).send('<ERROR>' + err + '</ERROR>');     
  }
};


来源:https://stackoverflow.com/questions/51518817/how-to-call-a-synchronous-sub-function-from-a-cloud-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!