简体   繁体   English

Node.js Twitter API游标

[英]Node.js Twitter API cursors

I'm using npm-twit to get followers of a specific account. 我正在使用npm-twit来获取特定帐户的关注者。

The Twitter API returns up to 5000 results from a single GET request. Twitter API从单个GET请求返回最多5000个结果。

If the user I'm querying has over 5000 followers a "next_cursor" value is returned with the data. 如果我查询的用户有超过5000个关注者,则返回带有数据的“next_cursor”值。

To get the next 5000 results, I need to re-run the GET function, passing it the "next_cursor" value as an argument. 为了获得接下来的5000个结果,我需要重新运行GET函数,并将“next_cursor”值作为参数传递给它。 I just can't seem to work out how to do it. 我似乎无法弄清楚如何做到这一点。

I was thinking a while loop, but I can't reset the global variable, I think because of scope: 我在想一个while循环,但是我无法重置全局变量,我认为是因为范围:

var cursor = -1

while ( cursor != 0 ) { 

  T.get('followers/ids', { screen_name: 'twitter' },  function (err, data, response) {

  // Do stuff here to write data to a file

  cursor = data["next_cursor"];

  })

}

Obviously I'm not a JS genius, so any help would be much appreciated. 显然我不是JS的天才,所以任何帮助都会非常感激。

The issue you are having is due to Node.js being asynchronous . 您遇到的问题是由于Node.js是异步的

T.get('followers/ids', { screen_name: 'twitter' },  function getData(err, data, response) {

  // Do stuff here to write data to a file

  if(data['next_cursor'] > 0) T.get('followers/ids', { screen_name: 'twitter', next_cursor: data['next_cursor'] }, getData);

  })

}

Please note: 请注意:

  1. I gave a name to the internal callback function. 我给内部回调函数命名了。 That is so that we can recursively call it from the inside. 这样我们就可以从内部递归调用它。
  2. The loop is replaced with a recursive callback. 循环被替换为递归回调。
  3. If there is a next_cursor data, then we call T.get using the same function getData . 如果有next_cursor数据,那么我们使用相同的函数getData调用T.get

Be aware that Do stuff here code will be executed many times (as many as there are next cursors). 请注意, Do stuff here代码将被执行多次(与下一个游标一样多)。 Since it is recursive callback - the order is guaranteed. 由于它是递归回调 - 订单是有保证的。


If you do not like the idea of recursive callbacks, you can avoid it by: 如果你不喜欢递归回调的想法,你可以通过以下方式避免它:

  1. Finding out beforehand all the next_cursor 's if possible, and generate requests using for loop. 如果可能,事先找出所有next_cursor ,并使用for循环生成请求。
  2. Alternatively, use asynchronous-helper modules like Async (though for learning purposes, I would avoid modules unless you are fluent in the concept already). 或者,使用异步辅助模块,如Async (虽然出于学习目的,我会避免使用模块,除非你已经熟悉这个概念)。

Consider testing with some 5K+ account. 考虑使用一些5K +帐户进行测试。

    const T = new Twit(tokens)

    function getFollowers (screenName, followers = [], cur = -1) {
      return new Promise((resolve, reject) => {
        T.get('followers/ids', { screen_name: screenName, cursor: cur, count: 5000 }, (err, data, response) => {
          if (err) {
            cur = -1
            reject(err)
          } else {
            cur = data.next_cursor
            followers.push(data.ids)
            if (cur > 0) {
              return resolve(getFollowers(screenName, followers, cur))
            } else {
              return resolve([].concat(...followers))
            }
          }
        })
      })
    }

    async function getXaqron () {
      let result = await getFollowers('xaqron')
      return result
    }

 console.log(getXaqron().catch((err) => {
  console.log(err) // Rate limit exceeded
}))

Struggled with this one.. Everything seemed to work, but data['next_cursor'] didn't change, EVER! 挣扎着这一个..一切似乎都有效,但数据['next_cursor']没有改变,永远!

Code should be like this: 代码应该是这样的:

T.get('followers/ids', { screen_name: 'twitter' },  function getData(err, data, response) {

  // Do stuff here to write data to a file

  if(data['next_cursor'] > 0) T.get('followers/ids', { screen_name: 'twitter', cursor: data['next_cursor'] }, getData);

  })

}

Parameter for Twit isn't "next_cursor", it's just "cursor" ;) Twit的参数不是“next_cursor”,它只是“光标”;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM