简体   繁体   English

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

[英]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: 当然,您将需要一些额外的东西:

  1. the 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 )还是在完成加载后推迟触发。
  2. the array for waiting callbacks that will be triggered upon load ( 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM