2015-01-18 2 views
5

Я использую npm-twit, чтобы получить подписчиков определенной учетной записи.Node.js Twitter API курсоры

API Twitter возвращает до 5000 результатов из одного запроса GET.

Если пользователь, которому я запрашиваю, имеет более 5000 подписчиков, возвращается значение «next_cursor» с данными.

Чтобы получить следующие результаты 5000, мне нужно повторно запустить функцию GET, передав ей значение «next_cursor» в качестве аргумента. Я просто не могу понять, как это сделать.

Я думал время цикла, но я не могу сбросить глобальную переменную, я думаю, что из-за объема:

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"]; 

    }) 

} 

Очевидно, я не JS гений, так что любая помощь будет высоко ценится ,

ответ

7

Вопрос, который у вас возникает, связан с тем, что 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); 

    }) 

} 

Обратите внимание:

  1. Я дал имя внутренней функции обратного вызова. Это значит, что мы можем рекурсивно называть это изнутри.
  2. Петля заменяется рекурсивным обратным вызовом.
  3. Если есть данные next_cursor, то мы вызываем T.get, используя ту же функцию getData.

Имейте в виду, что ли материал здесь код будет много раз выполняется (столько, сколько есть следующие курсоры). Поскольку это рекурсивный обратный вызов, заказ гарантирован.


Если вам не нравится идея рекурсивных обратных вызовов, вы можете избежать этого:

  1. Выяснить заранее все next_cursor «s, если это возможно, и генерировать запросы с использованием для петля.
  2. В качестве альтернативы используйте асинхронные вспомогательные модули, такие как Async (хотя для учебных целей я бы избегал модулей, если вы не владеете концепцией уже).
+0

Большое вам спасибо за помощь. Это имеет смысл для меня (и, конечно же, работает).Я исследовал Async, но чувствовал, что, вероятно, буду опережать себя, как вы предлагаете. – user1385827

0

Борясь с этим ... Все, казалось, сработало, но данные ['next_cursor'] не изменились, КОГДА-ЛИБО!

код должен быть таким:

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); 

    }) 

} 

Параметр для Twit не "next_cursor", это просто "курсор";)

1

Рассмотрим тестирование с некоторыми 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 
})) 
Смежные вопросы