[英]Nodejs exports.module How to export Variable to other Script
my goal is to get a list of files from a google drive folder and its subfolders as json string. 我的目标是从google驱动器文件夹及其子文件夹中获取文件列表作为json字符串。 so i can then use express to expose it as an API endpoint that other applications can connect to it.
这样我就可以使用express将它公开为其他应用程序可以连接到的API端点。
the code is working. 代码正在工作。 i get everything i want, but i do not know how to export my data variable to app.js
我得到了我想要的一切,但我不知道如何将我的数据变量导出到app.js
// get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
data
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data = JSON.stringify({ title : resp.title, description : resp.description, url : url});
//console.log(data);
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function() { return data; };
and in my app.js i use this 在我的app.js中
// app.js
var jsonData = require('./get-filelist');
console.log('output: ' + jsonData.files());
the data variable in app.js doesnt contain any data, while checking the output inside the function getFilesInfo() is working. 检查函数getFilesInfo()中的输出正常工作时,app.js中的数据变量不包含任何数据。
so, how to make my data variable accessible in other scripts? 因此,如何使我的数据变量可在其他脚本中访问?
You've got a problem with sync/async behavior. 您在同步/异步行为上遇到了问题。
app.js should be aware when to call the files() function exported from get-filelist
. app.js应该知道何时调用从
get-filelist
导出的files()函数。 The code you've got there calls the files() function immediately after requiring the get-filelist
module. 您需要的代码在需要
get-filelist
模块后立即调用files()函数。 At that moment the data
variable is still empty. 那时,
data
变量仍然为空。
Best solution would be to provide the files() function with a callback that will trigger once you've loaded the data
variable. 最好的解决方案是为files()函数提供一个回调,该回调将在您加载
data
变量后触发。
Of course, you will need some extras: 当然,您将需要一些额外的东西:
loaded
flag so that you know whether to trigger the callback immediately (if data
is already loaded) or postpone the trigger once the load is done. loaded
标志,以便您知道是立即触发回调(如果已加载data
)还是在完成加载后推迟触发。 callbacks
). callbacks
)。 // get-filelist.js
var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider,
request = require('request'),
async = require('async'),
loaded = false, //loaded? Initially false
callbacks = [], //callbacks waiting for load to finish
data = [];
const CLIENT_ID = "514...p24.apps.googleusercontent.com";
const CLIENT_SECRET = "VQs...VgF";
const REFRESH_TOKEN = "1/Fr...MdQ"; // get it from: https://developers.google.com/oauthplayground/
const FOLDER_ID = '0Bw...RXM';
async.waterfall([
//-----------------------------
// Obtain a new access token
//-----------------------------
function(callback) {
var tokenProvider = new GoogleTokenProvider({
'refresh_token': REFRESH_TOKEN,
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET
});
tokenProvider.getToken(callback);
},
//-----------------------------
// connect to google drive, look for the folder (FOLDER_ID) and list its content inclusive files inside subfolders.
// return a list of those files with its Title, Description, and view Url.
//-----------------------------
function(accessToken, callback) {
// access token is here
console.log(accessToken);
// function for token to connect to google api
var googleapis = require('./lib/googleapis.js');
var auth = new googleapis.OAuth2Client();
auth.setCredentials({
access_token: accessToken
});
googleapis.discover('drive', 'v2').execute(function(err, client) {
getFiles()
function getFiles(callback) {
retrieveAllFilesInFolder(FOLDER_ID, 'root' ,getFilesInfo);
}
function retrieveAllFilesInFolder(folderId, folderName, callback) {
var retrievePageOfChildren = function (request, result) {
request.execute(function (err, resp) {
result = result.concat(resp.items);
var nextPageToken = resp.nextPageToken;
if (nextPageToken) {
request = client.drive.children.list({
'folderId': folderId,
'pageToken': nextPageToken
}).withAuthClient(auth);
retrievePageOfChildren(request, result);
} else {
callback(result, folderName);
}
});
}
var initialRequest = client.drive.children.list({
'folderId': folderId
}).withAuthClient(auth);
retrievePageOfChildren(initialRequest, []);
}
function getFilesInfo(result, folderName) {
data = []; //data is actually an array
result.forEach(function (object) {
request = client.drive.files.get({
'fileId': object.id
}).withAuthClient(auth);
request.execute(function (err, resp) {
// if it's a folder lets get it's contents
if(resp.mimeType === "application/vnd.google-apps.folder"){
retrieveAllFilesInFolder(resp.id, resp.title, getFilesInfo);
}else{
/*if(!resp.hasOwnProperty(folderName)){
console.log(resp.mimeType);
}*/
url = "http://drive.google.com/uc?export=view&id="+ resp.id;
html = '<img src="' + url+ '"/>';
// here do stuff to get it to json
data.push(JSON.stringify({ title : resp.title, description : resp.description, url : url}));
//console.log(resp.title);console.log(resp.description);console.log(url);
//.....
}
});
});
//console.log(data); //now, that the array is full
//loaded is true
loaded = true;
//trigger all the waiting callbacks
while(callbacks.length){
callbacks.shift()(data);
}
}
});
}
]);
// export the file list as json string to expose as an API endpoint
console.log('my data: ' + data);
exports.files = function(callback) {
if(loaded){
callback(data);
return;
}
callbacks.push(callback);
};
Now the app.js behavior needs to change: 现在,app.js的行为需要改变:
// app.js
var jsonData = require('./get-filelist');
jsonData.files(function(data){
console.log('output: ' + data);
});
/* a much more elegant way:
jsonData.files(console.log.bind(console,'output:'));
//which is actually equivalent to
jsonData.files(function(data){
console.log('output: ',data); //without the string concatenation
});
*/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.