2014-09-21 243 views
0

我的目標是從谷歌驅動器文件夾及其子文件夾獲取文件列表作爲json字符串。所以我可以使用express將它暴露爲其他應用程序可以連接到它的API端點。Nodejs exports.module如何將變量導出到其他腳本

該代碼正在工作。我得到我想要的一切,但我不知道怎麼我的數據變量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; }; 

,並在我的app.js出口我用這個

// app.js 
var jsonData = require('./get-filelist'); 

console.log('output: ' + jsonData.files()); 

數據變量的應用程序。 js不包含任何數據,同時檢查函數getFilesInfo()內的輸出正在工作。

那麼,如何讓我的數據變量可以在其他腳本中訪問?

+0

您是不是要找'的console.log( '輸出:' + jsonData.files());'? (調用函數) – Scimonster 2014-09-21 11:02:21

+0

是的。你是對的。它應該在app.js console.log('output:'+ jsonData.files())中讀取;謝謝。 但仍然,我的數據變量不包含任何值。 – ron 2014-09-21 11:05:45

回答

0

您遇到了同步/異步行爲問題。

app.js應該知道調用從get-filelist導出的文件()函數。您需要get-filelist模塊後,您在那裏的代碼會立即調用files()函數。此時data變量仍爲空。

最好的解決方案是提供文件()函數的回調,一旦你加載了變量data就會觸發。所以,你知道是否立即觸發回調(如果data已經裝入)或推遲觸發一旦負載完成

  1. loaded標誌:

    當然,你需要一些額外的。

  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 
}); 
*/ 
+0

正確!謝謝。有用。 從來沒有想過自己! – ron 2014-09-21 12:51:41

+0

它的作品,但它只包含一個條目,而不是整個列表。 爲什麼會發生這種情況? – ron 2014-09-21 13:14:52

+0

也許你發佈了更多的代碼,以便我可以看一看。您使用JSON.stringify生成的數據將通過回調進行發送。如果數據包含一個條目,回調將得到一個條目... – 2014-09-21 14:03:23

相關問題