nodejs Google API中的回调链接

时间:2018-01-09 16:35:38

标签: javascript node.js api

我有两个文件,app.jssheets.js。我想将app.js中的数据传递到调用Google表格API的sheets.js,然后在完成readData()函数中的api调用后返回一个值。

问题如下: 当我尝试将response中的app.js的值作为Sheets.readData(data)返回时,它将返回为未定义。我相信回调链中的某些内容不允许将readData()的返回值传递到readSheet(),因此返回undefined。我在readSheet中错过了一个可以返回authorize()结果的回调吗?或者我在其他地方错过了回调函数?谢谢。

// Load client secrets from a local file.
exports.readSheet = function(data, callback) {
  let response = fs.readFile('client_secret.json', function processClientSecrets(err, content) {
    if (err) {
      console.log('Error loading client secret file: ' + err);
      return;
    }
    // Authorize a client with the loaded credentials, then call the
    // Google Sheets API.
    authorize(JSON.parse(content), data), readData);
  });

 return response;
}

/**
 * Create an OAuth2 client with the given credentials, and then execute the
 * given callback function.
 *
 * @param {Object} credentials The authorization client credentials.
 * @param {function} callback The callback to call with the authorized client.
 */
function authorize(credentials, data, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];
  var auth = new googleAuth();
  var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

  // Check if we have previously stored a token.
  fs.readFile(TOKEN_PATH, function(err, token) {
    if (err) {
      getNewToken(oauth2Client, callback);
    } else {
      oauth2Client.credentials = JSON.parse(token);
      callback(oauth2Client, data);
    }
  });
}

function readData(auth, data) {
  var sheets = google.sheets('v4');
  sheets.spreadsheets.values.get({
    auth: auth,
    spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
    range: 'Class Data!A2:E',
  }, function(err, response) {
    if (err) {
      console.log('The API returned an error: ' + err);
      return;
    }
    var rows = response.values;
    if (rows.length == 0) {
      console.log('No data found.');
    } else {
      /* Return value here
      let data = data + 'hello world';
      return data
      */
    }
  });
}

1 个答案:

答案 0 :(得分:0)

readData以异步方式运行,并且取决于sheets.spreadsheets.values.get的异步完成。有几种方法可以解决这个问题。最简单的方法是将回调函数传递给readData

function readData(auth, data, cb) {
  /* your code here */
    } else {
      // successful response from sheets
      cb(null, response);
    }
  });
}

然后,您必须将来电更新为authorize才能致电callback,而不仅仅是readData

authorize(JSON.parse(content), data, (auth, data) => readData(auth, data, callback);

但据我所知,Google API支持承诺。编写代码以使用promises会更容易/更清晰。您可以将mz库用于具有承诺支持的fs方法。

// NOTE! This is a simple example with no error handling

exports.readSheet = async function (data) {
  const content = fs.readFile('client_secret.json');
  const [auth, data] = authorize(JSON.parse(content), data);

  return readData(auth, data);
}

async function authorize(credentials, data, callback) {
  var clientSecret = credentials.installed.client_secret;
  var clientId = credentials.installed.client_id;
  var redirectUrl = credentials.installed.redirect_uris[0];
  var auth = new googleAuth();
  var oauth2Client = new auth.OAuth2(clientId, clientSecret, redirectUrl);

  const token = await fs.readFile(TOKEN_PATH);
  oauth2Client.credentials = JSON.parse(token);
  return [oauth2Client, data];
}

async function readData(auth, data) {
  const sheets = google.sheets('v4');
  return sheets.spreadsheets.values.get({
    auth: auth,
    spreadsheetId: '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms',
    range: 'Class Data!A2:E',
  });
}