2013-08-20 77 views
0

我一直在用coffeescript中的node.js來玩弄一些來自reddit.com的json接口的一些故事,但運行時遇到了一些障礙。變量不在循環中更新正確

我想解析來自http://www.reddit.com/r/programming/.json的json,然後附加一個帶有參數countafter並重新分析的查詢語句。重複根據傳遞給get_stories()

當我運行下面的代碼爲file.js > test.txt我得到意想不到的結果。 (見下文)它看起來像querystring.count正在更新,但它們都匹配最後一遍URL中的URL。不知道爲什麼我沒有看到count = 0,25,50,75,125。此外,querystring.after不在網址上。到底是怎麼回事?

代碼:

# Requires 
request = require 'request' 
qs = require 'querystring' 
mongojs = require 'mongojs' 

# Connect to db 
db = mongojs 'mongodb://localhost/feedtraining', ['subreddit_stories'] 

get_stories = (subreddit, {per_page, pages}, storyCallback) -> 
    current_page = 0 
    querystring = {} 

    while true 
     querystring.count = current_page * per_page 

     request_uri = "http://www.reddit.com/r/#{subreddit}/.json?#{qs.stringify querystring}" 

     request 
      uri: request_uri, 
      json: true, 
      (error, response, body) -> 
       if !error and response.statusCode == 200 
        for item in body.data.children 
         if item.data.selftext_html is null 
          storyCallback request_uri, current_page, item.data 

        querystring.after = body.data.children[body.data.children.length-1].id 
       else 
        console.log error 

       return 

     if current_page == pages then break else current_page++ 

    return 

get_stories 'programming', {per_page: 25, pages: 5}, (request_uri, page, story) -> 
    db.subreddit_stories.insert(story) 
    console.log request_uri 

輸出:

http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 
http://www.reddit.com/r/programming/.json?count=125 

回答

1

[編輯]

如果需要連鎖異步操作,如爲下request設置querystring.after,你贏了」不能使用while。循環將運行至完成,在其中任何一個完成之前開始全部request s,並且可以設置querystring.after

您可以重寫與function S中的迭代爲延續所以每個請求將等到after可從之前的請求。

附註:由於after應該已經移動了收集的開始,您可能希望保留count相同的值。否則,集合的大小將隨着每個請求而增加。

get_stories = (subreddit, {per_page, pages}, storyCallback) -> 
    current_page = 0 

    send_next_request = (querystring = {}) -> 
     querystring.count = per_page 

     request_uri = "http://www.reddit.com/r/#{subreddit}/.json?#{qs.stringify querystring}" 

     request 
      uri: request_uri, 
      json: true, 
      (error, response, body) -> 
       if !error and response.statusCode == 200 
        for item in body.data.children 
         if item.data.selftext_html is null 
          storyCallback request_uri, current_page, item.data 

        current_page++ 
        if current_page < pages 
         send_next_request(after: body.data.children[body.data.children.length-1].id) 

    send_next_request() 

[原件]

你需要創建一個closure周圍request_uri

request_uri = "http://www.reddit.com/r/#{subreddit}/.json?#{qs.stringify querystring}" 

do (request_uri) -> 
    request 
    url: request_uri, 
    # ... 

JavaScript和反過來的CoffeeScript,不(yet)具有塊作用域,因此,只有1 request_uri爲整個循環創建,並且可以只保留值1。

添加在request是異步的,while true環將之前運行完成:

storyCallback request_uri, current_page, item.data 

對任何請求進行評估。而且,這個點上的request_uri將始終具有它在循環中給出的最後一個值。

閉合創建了一個額外的function範圍,因此每個迭代while true都可以有自己的request_uri


Loops and Comprehensions下記載:

當使用JavaScript的循環產生的功能,它的共同插入一個封閉的包裝,以確保循環變量被關閉了,所有的生成函數不只是分享最終值。 CoffeeScript提供了do關鍵字,該關鍵字立即調用傳遞的函數,轉發任何參數。

for filename in list 
    do (filename) -> 
    fs.readFile filename, (err, contents) -> 
     compile filename, contents.toString() 
+0

這對uri很有用!對於爲什麼'after'參數沒有顯示在任何uris上的任何見解?也是因爲代碼的異步性質。任何方式讓它起作用? – Kylee

+0

@Kylee這是因爲'while'循環已經完成,並且在完成設置'querystring.after'之前已經啓動了所有'請求'。看到我的編輯更多。 –

+0

工作!我知道異步導致了很多這些問題,但不知道如何解決這些問題。所以用於服務器端的python,客戶端的JavaScript。 – Kylee