0

reddit.com の json インターフェイスからいくつかのストーリーを取得するために、coffeescript で node.js をいじっていましたが、問題が発生しました。

json を解析してから、パラメーターと再解析http://www.reddit.com/r/programming/.jsonを使用してクエリ ステートメントを追加したいと考えています。渡された引数に基づいて繰り返すcountafterget_stories()

以下のコードを実行すると、file.js > test.txt予期しない結果が得られます。(以下を参照)querystring.countが更新されているように見えますが、それらはすべて、最後のパスの URL がどのように見えるかに一致します。count=0,25,50,75,125 が表示されない理由がわかりません。また、querystring.afterURLには存在しません。何が起こっている?

コード:

# 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
4

1 に答える 1

1

[編集]

querystring.after次の の設定など、非同期アクションをチェーンする必要がある場合はrequest、 を使用できませんwhile。ループは完了するまで実行され、いずれかが終了して設定できるようになるrequest前に、すべての が開始されます。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()

オリジナル

の周りにクロージャを作成する必要がありますrequest_uri

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

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

JavaScript、そして CoffeeScript には (まだ) ブロック スコープがないrequest_uriため、ループ全体に対して 1 つのみが作成され、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()
于 2013-08-20T21:22:22.783 に答える