2013-10-28 220 views
3

我正在編寫一個簡單的Node.JS應用程序,它可以與GitHub API一起使用來提取用戶統計信息。我正在向/repos/:user/:repo_name/stats/contributors發送GET請求,該請求應該返回給我一個JSON字符串。這裏是我的功能:JSON.parse將空數組附加到字符串參數的末尾

function getRepoCommits(token,repos,user,callback) { 
    for (var i=0; i<repos.length; i++) { 
     var returnChunk = ''; 
     var full_name = repos[i].full_name; 
     //console.log(full_name); 
     var options = { 
      host: 'api.github.com', 
      path: '/repos/'+full_name+'/stats/contributors', 
      method: 'GET', 
      headers: { 
       'Accept': 'application/json', 
       'Authorization': 'token '+token, 
       'Content-Type': 'application/x-www-form-urlencoded', 
      } 
     }; 

     var request = https.request(options, function(res) { 
      //res.setEncoding('utf8'); 
      res.on('data', function(chunk) { 
       returnChunk += chunk; 
      }); 
      res.on('end', function(chunk) { 
       console.log(returnChunk); 
       var stats = JSON.parse(returnChunk); 
       console.log(stats.length); 
       for (var j=0;j<stats.length;j++) { 
       } 
       if (i == repos.length-1) { 
        //callback(); 
       } 
      }) 
     }); 

     request.on('error',function(err) { 
      callback(err); 
      console.log(err); 
     }); 
     request.end(); 
    } 
} 

感興趣的區域就在這裏:

  res.on('end', function(chunk) { 
       console.log(returnChunk); 
       var stats = JSON.parse(returnChunk); 
       console.log(stats.length); 
       for (var j=0;j<stats.length;j++) { 
       } 
       if (i == repos.length-1) { 
        //callback(); 
       } 
      }) 

當我檢查的returnChunk的價值,它是一個有效的JSON字符串格式爲:

[{json}] 

但是,當功能達到JSON.parse時,會報錯:

SyntaxError: Unexpected token [

基本上,在分析字符串之前,會在字符串的末尾附加一個額外的[]。它成爲

[{json}][] 

我試過幾個小時就結束弄清楚如何處理這個問題,但我似乎無法找出它爲什麼是這樣做的。有什麼想法嗎?

+0

你是什麼意思它追加'[]'到底?你在哪裏看到你的日誌? –

+2

我看到發生了什麼。你在一個循環中做了幾個異步請求,並且把它們全部追加到同一個'returnChunk'變量中,這樣所有的數據就會混合在一起。請記住,JavaScript沒有塊範圍,只有函數範圍,所以就好像你在函數的頂部放了'var returnChunk =「」'。 –

+1

@BlueSkies - 你應該發佈這個答案... –

回答

3

您正在循環中創建多個異步請求,並將它們全部附加到相同的returnChunk變量,因此所有數據都混合在一起。

請記住,JavaScript沒有塊範圍,只有函數範圍,所以就好像你把var returnChunk = ""放在函數的頂部。

解決方案將使用.forEach()而不是for語句,以便回調爲您提供每個迭代的新範圍。

repos.forEach(function(repo, i) { 
    var returnChunk = ''; 
    var full_name = repo.full_name; 
    //console.log(full_name); 
    var options = { 
     host: 'api.github.com', 
     path: '/repos/'+full_name+'/stats/contributors', 
     method: 'GET', 
     headers: { 
      'Accept': 'application/json', 
      'Authorization': 'token '+token, 
      'Content-Type': 'application/x-www-form-urlencoded', 
     } 
    }; 

    var request = https.request(options, function(res) { 
     //res.setEncoding('utf8'); 
     res.on('data', function(chunk) { 
      returnChunk += chunk; 
     }); 
     res.on('end', function(chunk) { 
      console.log(returnChunk); 
      var stats = JSON.parse(returnChunk); 
      console.log(stats.length); 
      for (var j=0;j<stats.length;j++) { 
      } 

// !!! This will be unreliable because you don't know which one will finish last. 
//  You could maintain a separate counter that is incremented as each "end" fires 
//  to make sure the `callback()` happens on the last one. 
      if (i == repos.length-1) { 
       //callback(); 
      } 
     }) 
    }); 

    request.on('error',function(err) { 
     callback(err); 
     console.log(err); 
    }); 
    request.end(); 
}); 
+0

感謝一堆!它工作完美。這是我要學習多少東西的時刻之一!我會upvote,但我沒有足夠的代表點! – thecalvinchan

+0

很高興幫助。 –

相關問題