我是初学者,所以我会尝试以最好的方式揭露我的问题。我正在尝试在服务器端调用Google AnalyticsAPI,以在客户端使用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
据我所知,data
未定义,因为analytics
未定义。并且analytics
未定义,因为此调用:
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
let analytics = google.analytics('v3');
data = queryData(analytics);
});
是异步调用。我想是client_id加载的时间。
那么如何编写此脚本以便queryData
仅在此部分运行时运行:
let analytics = google.analytics('v3');
data = queryData(analytics);
准备好了吗?
我希望我的问题清楚明白,对你有意义。我读过有关async / await模块的信息。但是我不能自己使用它。
编辑#1:我需要使用类似的东西,但我不确定如何
module.exports = {queryData: function (err, req, res, next) { next(); }};
答案 0 :(得分:3)
您在此处将analytics
定义为本地变量:
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
let analytics = google.analytics('v3');
queryData(analytics);
});
然后期望它在导出中的queryData(analytics)
处可用。
您可以做的是在承诺中解决您的authorize
调用(因为首次初始化时会出现竞争条件,因此您可以将其包含在承诺中并等待它解决致电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
是否提供了承诺API,所以我只是使用bluebird“宣传”它。