如何从 Cloud Functions 调用同步子函数

How to call a synchronous sub function from a Cloud Function

我想 运行 我的所有功能同步。但是,如果我执行类似下面代码的操作,响应将在分配 return 值之前发回。

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;
}

即控制台输出类似于:

<OUTPUT>undefined</OUTPUT> 

并且在 Stackdriver 日志中会显示这样的执行顺序:

 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

这是将执行锁定为仅同步行为的优雅方式吗?

解决方案

Alexandru 在下面建议的 async/await 方法行之有效!谢谢亚历山德鲁。

注意:但是 不适用于 standard/GA Cloud Functions。您将不得不使用 Google Cloud Functions Node.js v8 Beta

是的,有你可以看看async/await

你的代码最终会看起来像这样:

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;
  }
}

而在第二个

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>');     
  }
};