Node Twitter库具有多种回调功能

时间:2018-12-13 17:38:49

标签: node.js asynchronous twitter callback

我正在尝试使用Twitter for Node向Twitter发送请求,并将响应存储在数组中以供以后处理。我正在将返回的tweet推入数组,每个push()都发生在回调中,这似乎工作正常。 我的问题是我无法通过所有推送的推文访问整个阵列。

当然,原因是在Twitter API的结果到达之前,调用该数组的任何尝试都会被调用,所以我得到了一个空数组。

如何(也应该)使我的函数与完整数组一起工作到另一个回调中?我是从有人仍想牢牢掌握异步编程的角度出发的,尤其是必须异步运行的多个回调或函数。

同样,当前结果是tweetHold = [],我希望tweetHold包含searchArray中所有用户的所有匹配推文。

let searchArray = {
  users: ['ByBuddha', 'thetweetofgod']
}

let tweetHold = [];  

let T = new Twitter(config);

for (user of searchArray.users) {

  let params = {
    q: 'from:'+ user,
    count: 1,
    tweet_mode: 'extended',
    result_type: 'recent',
    lang: 'en'
  }

  T.get('search/tweets', params, returnedTweets);

}

function returnedTweets(err, tweets, response) {
  tweetHold.push(tweets);
}

// obviously, doesn't work as the array is logged to console before T.get() is done
console.log(tweetHold);

1 个答案:

答案 0 :(得分:0)

T.get接受一个回调函数,异步操作完成后将被调用。但是,由于您希望获得的是 multiple 响应,而不仅仅是一个响应,因此仅使用回调本身会有些混乱。例如,在returnedTweets内,您可以增加一个持久计数器变量,然后一次counter === searchArray.users.length调用下一个函数,但是改用Promises会更优雅。

将每个T.get调用映射到一个Promise解析的tweets变量,然后在这些Promises数组上调用Promise.allPromise.all接受一个Promises的数组,并返回一个Promise,一旦传递的数组中的每个Promise都解决了,它就会解决。

请注意,您似乎正在忽略可能从err返回的T.get-这可能不是一个好主意,最好能够检查何时发生错误,然后以某种方式处理错误(否则,tweetHold数组有时可能包含损坏的数据)。幸运的是,如果您使用Promises,则实现起来很容易-如果有reject,只需err,然后在catch之后添加Promise.all

const T = new Twitter(config);
const searchObject = {
  users: ['ByBuddha', 'thetweetofgod']
};

const searchPromises = searchArray.users.map((user) => {
  return new Promise((resolve, reject) => {
    const params = {
      q: 'from:'+ user,
      count: 1,
      tweet_mode: 'extended',
      result_type: 'recent',
      lang: 'en'
    };
    T.get('search/tweets', params, (err, tweets) => {
      if (err) reject(err);
      else resolve(tweets);
    });
  });
});

Promise.all(searchPromises)
  .then((tweetHold) => {
    // tweetHold will be an array containing the `tweets` variable for each user searched
    console.log(tweetHold);
  })
  .catch((err) => {
    // there was an error, best to handle it somehow
    // the `.then` above will not be entered
  });