2015-05-21 35 views
0

我試圖運行一個函數,一旦該函數完成,然後運行另一個函數。第一個函數讀取一個CSV文件,發出GET請求並構建一個對象。第二個函數使用新創建的對象來創建一個新的CSV文件。Node.js異步 - 從循環建立對象,然後做對象

我遇到的問題是在GET請求完成之前創建新的CSV文件。

我使用async.parallel來設置流程,但無法獲得正確的邏輯。

我很想知道我做錯了什麼,並且更好地理解節點如何看待這些任務。

// Require 
var request = require('request'); 
var fs = require('fs'); 
var json2csv = require('json2csv'); 
var csv = require('csv'); 
var async = require('async'); 

// Params 
var emailHunter_apiKey = '0000'; 
var emails = []; 
var fields = ['email']; 
var i = 0; 

// Start 
async.parallel([ 
     function(callback){ 
      setTimeout(function(){ 
       var file = fs.readFileSync('file.csv'); 
       csv.parse(file, {delimiter: ','}, function (err, data) { 
        for (var key in data) { 
         if (i < 5) { 
          if (data.hasOwnProperty(key)) { 
           var h = data[key]; 
           if (h[5] != '') { 
            var url = h[5]; 
            url = url.replace('//', ''); 
            url = url.replace('www.', ''); 
            request('https://api.emailhunter.co/v1/search?domain=' + url + '&api_key=' + emailHunter_apiKey + '', function (error, response, body) { 
             if (!error && response.statusCode == 200) { 
              var json = JSON.parse(body); 
              for (var subObj in json) { 
               if (json.hasOwnProperty(subObj) && subObj == 'emails') { 
                var emailObj = json[subObj]; 
                for (var key in emailObj) { 
                 var email = { 
                  'email': emailObj[key]['value'] 
                 }; 
                 emails.push(email); 
                } 
               } 
              } 
             } 
            }); 
           } 
          } 
         } 
         i++; 
        } 
       }); 
       callback(null, emails); 
      }, 200); 
      console.log(emails); 
     } 
    ], 
    function(err, results){ 
     json2csv({data: results, fields: fields}, function (err, csv) { 
      if (err) console.log(err); 
      fs.writeFile('export.csv', csv, function (err) { 
       if (err) throw err; 
       console.log('file saved'); 
      }); 
     }); 
     console.log(results); 
    }); 
+0

首先,你在使用'async.parallel'錯了,因爲你只有在它的第一個參數1種功能。它應該採取一系列(多個)功能。其次,我認爲Promises可能更適合您的需求,並對這些進行調查。基本上,你依賴於多次執行'request'(這是異步),所以你需要提交它並檢查所有的promise是否已經解決。當你發現承諾時你會更多地瞭解它。最後,爲了可讀性,你的代碼是一個[你應該避免的回調 - 地獄](http://stackoverflow.com/a/29349325/1266650)。 – laggingreflex

+0

感謝您爲此付諸流水。我肯定試圖圍繞回調結構來理解節點如何思考/工作。這對承諾建議也有意義。再次感謝您的幫助! –

回答

0

由於laggingreflex提到,您正在錯誤地使用異步。

首先你應該建立一個你想並行執行的函數數組。然後使用異步來執行它們。

此外,您的回調正在立即執行,因爲csv.parse()是一個異步函數。因此節點立即觸發它,然後執行回調()。您需要在parse()內移動回調。

嘗試......

// Params 
var emailHunter_apiKey = '0000'; 
var emails = []; 
var fields = ['email']; 
var i = 0; 
var functionsToRunAsync = []; 

var file = fs.readFileSync('file.csv'); 
csv.parse(file, {delimiter: ','}, function (err, data) { 
    for (var key in data) { 
     if (i < 5) { 
      if (data.hasOwnProperty(key)) { 
       var h = data[key]; 
       if (h[5] != '') { 
        var url = h[5]; 
        url = url.replace('//', ''); 
        url = url.replace('www.', ''); 

        // add a new function to an array, to be executed later 
        functionsToRunAsync.push(function(callback) { 
         request('https://api.emailhunter.co/v1/search?domain=' + url + '&api_key=' + emailHunter_apiKey + '', function (error, response, body) { 
          if (!error && response.statusCode == 200) { 
           var json = JSON.parse(body); 
           for (var subObj in json) { 
            if (json.hasOwnProperty(subObj) && subObj == 'emails') { 
             var emailObj = json[subObj]; 
             for (var key in emailObj) { 
              var email = { 
               'email': emailObj[key]['value'] 
              }; 
              emails.push(email); 

              // callback to tell async this function is complete 
              callback() 
             } 
            } 
           } 
          } else { 
           // callback to tell async this function is complete 
           callback 
          } 
         }); 
        }); 

       } 
      } 
     } 
     i++; 
    } 

    // now that we have all of the functions in an array, we run them in parallel 
    async.parallel(

     functionsToRunAsync, 

     function(err, results) { // all async functions complete 
      json2csv({data: results, fields: fields}, function (err, csv) { 
       if (err) console.log(err); 
       fs.writeFile('export.csv', csv, function (err) { 
        if (err) throw err; 
        console.log('file saved'); 
       }); 
      }); 
      console.log(results); 
    }); 
}); 
+0

非常感謝您爲此貫穿始終。這更有意義,它的工作。我喜歡這個並行函數數組的想法。前幾天我剛剛開始使用節點,開始學習小腳本。 –