迷失在回调地狱与Node, Express和谷歌分析API
Lost in callback hell with Node, Express and google Analytics API
我是新手,所以我会尽量以最好的方式暴露我的问题。我试图调用谷歌分析API在服务器端显示一些数据在客户端与反应和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(); }};
您在这里将analytics
定义为局部变量:
jwtClient.authorize(function (err, tokens) {
if (err) {
console.log(err);
return;
}
let analytics = google.analytics('v3');
queryData(analytics);
});
然后期望它在queryData(analytics)
中可用。
你可以做的是在一个promise中解析你的authorize
调用(因为当它第一次初始化时会有一个竞争条件,所以你可以把它包装在一个promise中,等待它在能够调用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,所以我只是"承诺"它使用蓝鸟。
相关文章:
- 三星智能电视应用程序使用谷歌API
- 在谷歌api v3中使用地理自动完成功能获取邮政编码
- 从谷歌API地理代码的形式字段到数据库
- 从名称或邮政编码获取纬度和经度-谷歌API
- 英国邮政编码谷歌API不返回街道地址
- 用于谷歌API的Jquery
- 根据谷歌 Api v3 书/也用一个按钮添加一个标记
- 谷歌 API :仪表动画
- (谷歌API)单元格引用中的动态工作表和工作表创建脚本的名称
- 谷歌APi 不检索值
- 一个回调两个异步函数,一个是谷歌 api getDistanceMatrix
- 谷歌API正在计算无效地址的距离
- 在文件系统中使用谷歌API
- 如何对谷歌 API 搜索查询进行编码
- 如何使用谷歌API从街景切换到路线图
- 谁能告诉我为什么我不能从谷歌 API 获得城市列表
- 如何使用谷歌 API 网页版从address_components获取地点 ID
- 从经度和纬度谷歌 API 获取邮政编码
- 动态向下面的透视柱形图添加注释 - 谷歌 API
- 谷歌 API 图表日志刻度不起作用