Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 迷失在Node、Express和google Analytics API的回调地狱中_Javascript_Node.js_Asynchronous_Async Await - Fatal编程技术网

Javascript 迷失在Node、Express和google Analytics API的回调地狱中

Javascript 迷失在Node、Express和google Analytics API的回调地狱中,javascript,node.js,asynchronous,async-await,Javascript,Node.js,Asynchronous,Async Await,我是这里的初学者,所以我会尽力以最好的方式揭露我的问题。我试图在服务器端调用Google Analytics API,用react和d3在客户端显示一些数据。下面是我调用GA api的脚本: var google = require ("googleapis"); var key = require ('./client_id.json'); const VIEW_ID = 'ga:80820965'; let jwtClient = new google.auth.JWT( key.c

我是这里的初学者,所以我会尽力以最好的方式揭露我的问题。我试图在服务器端调用Google Analytics API,用react和d3在客户端显示一些数据。下面是我调用GA api的脚本:

var google = require ("googleapis");
var key = require ('./client_id.json');

const VIEW_ID = 'ga:80820965';

let jwtClient = new google.auth.JWT(
  key.client_email, 
  null,
  key.private_key,
  ['https://www.googleapis.com/auth/analytics.readonly'],
  null
);

    jwtClient.authorize(function (err, tokens) {
      if (err) {
        console.log(err);
        return;
      }
      let analytics = google.analytics('v3');
        queryData(analytics);
    });

var queryData = function(analytics) {
      analytics.data.ga.get({
        'auth': jwtClient,
        'ids': VIEW_ID,
        'metrics': 'ga:uniquePageviews',
        'dimensions': 'ga:pagePath',
        'start-date': '30daysAgo',
        'end-date': 'yesterday',
        'sort': '-ga:uniquePageviews',
        'max-results': 10,
      }, function (err, response) {
        if (err) {
          console.log(err);
          return;
        }
        console.log(JSON.stringify(response, null, 4));
      });  
    }


module.exports = {
    queryData
};
当我独立调用这个脚本时,一切都很好,但是当我在整个项目中调用它时,我出现了以下错误:

[1]   analytics.data.ga.get({
[1]            ^
[1] 
[1] TypeError: Cannot read property 'data' of undefined
据我所知,
数据
未定义,因为
分析
未定义。而
分析
未定义,因为此调用:

   jwtClient.authorize(function (err, tokens) {
      if (err) {
        console.log(err);
        return;
      }
      let analytics = google.analytics('v3');
        data = queryData(analytics);
    });
是一个异步调用。我猜客户端id加载的时间

那么,如何编写此脚本,使
queryData
仅在以下情况下运行:

let analytics = google.analytics('v3');
        data = queryData(analytics);
准备好了吗

我希望我的问题是明确的,对你有意义。我已经读过异步/等待模块。然而,我不能自己使用它

编辑#1:我需要使用类似的东西,但我不确定如何使用

module.exports = {queryData: function (err, req, res, next) { next(); }};

您在此处将
分析定义为局部变量:

jwtClient.authorize(function (err, tokens) {
  if (err) {
    console.log(err);
    return;
  }
  let analytics = google.analytics('v3');
    queryData(analytics);
});
然后希望它可以在导出的
queryData(analytics)
中找到

相反,您可以做的是在承诺中解析
授权
调用(因为在它首次初始化时会有竞争条件,所以您可以将它包装在承诺中,等待它解析后才能调用
queryData
)。大概是这样的:

var google = require ("googleapis");
var key = require ('./client_id.json');
const Promise = require('bluebird');
var authorizationPromise;

const VIEW_ID = 'ga:80820965';

let jwtClient = new google.auth.JWT(
  key.client_email, 
  null,
  key.private_key,
  ['https://www.googleapis.com/auth/analytics.readonly'],
  null
);

authorizationPromise = Promise.promisify(jwtClient.authorize)()
.then(function (err, tokens) {
  if (err) {
    throw new Error(err);
  }

  return google.analytics('v3');
})
.catch(function(err) {
  console.log(err);
});

var queryData = function() {
  authorizationPromise.then(function(analytics) {
      analytics.data.ga.get({
        'auth': jwtClient,
        'ids': VIEW_ID,
        'metrics': 'ga:uniquePageviews',
        'dimensions': 'ga:pagePath',
        'start-date': '30daysAgo',
        'end-date': 'yesterday',
        'sort': '-ga:uniquePageviews',
        'max-results': 10,
      }, function (err, response) {
        if (err) {
          console.log(err);
          return;
        }
        console.log(JSON.stringify(response, null, 4));
      }); 
  });
};

module.exports = {
    queryData
};

我不确定
jwtClient.authorize
是否提供了promise API,所以我只是用它“promisified”了。

好的,非常感谢。我现在真的明白我的问题了。但是,我尝试了您的代码,并出现以下错误
无法读取未定义的属性“refreshToken”
,知道这是从哪里来的吗?@SimonBreton,没问题。我不知道,我还没有测试上面的代码。我刚刚为这种情况实现了一个非常常见的模式,但是您可能需要遍历堆栈跟踪并调查错误的来源。对不起,我帮不上什么忙了。如果您在继续过程中有任何其他问题,请告诉我……您能给我一点关于
授权承诺
代码的详细信息吗。我尤其不理解
标记
变量的用法。谢谢