Nodejsexports.module如何将变量导出到其他脚本



我的目标是以json字符串的形式从谷歌驱动器文件夹及其子文件夹中获取文件列表。这样我就可以使用express将其公开为API端点,其他应用程序可以连接到它

代码正在工作。我得到了我想要的一切,但我不知道如何将我的数据变量导出到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; };

在我的应用程序.js中,我使用这个

// app.js
var jsonData = require('./get-filelist');
console.log('output: ' + jsonData.files());

在检查函数getFilesInfo()内部的输出时,app.js中的数据变量不包含任何数据。

那么,如何在其他脚本中访问我的数据变量呢?

同步/异步行为出现问题。

当调用从get-filelist导出的files()函数时,app.js应该注意。这里的代码在需要get-filelist模块后立即调用files()函数。此时,data变量仍然为空。

最好的解决方案是为files()函数提供一个回调,该回调将在加载data变量后触发。

当然,你需要一些额外的东西:

  1. loaded标志,以便您知道是立即触发回调(如果data已经加载)还是在加载完成后推迟触发
  2. 用于等待将在加载时触发的回调的数组(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);
};

现在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
});
*/

相关内容

  • 没有找到相关文章

最新更新