Javascript 迷失在Node、Express和google Analytics API的回调地狱中
我是这里的初学者,所以我会尽力以最好的方式揭露我的问题。我试图在服务器端调用Google Analytics API,用react和d3在客户端显示一些数据。下面是我调用GA 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
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,没问题。我不知道,我还没有测试上面的代码。我刚刚为这种情况实现了一个非常常见的模式,但是您可能需要遍历堆栈跟踪并调查错误的来源。对不起,我帮不上什么忙了。如果您在继续过程中有任何其他问题,请告诉我……您能给我一点关于授权承诺
代码的详细信息吗。我尤其不理解标记
变量的用法。谢谢