首页 > 解决方案 > 使用 Node Twitter 库的多个回调函数

问题描述

我正在尝试使用Twitter for Node向 Twitter 发出请求,并将响应存储在一个数组中以供以后处理。我正在将返回的推文推送到一个数组,每个推文都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);

标签: node.jsasynchronoustwittercallback

解决方案


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

T.get将每个调用映射到使用您感兴趣Promise的变量解析的a,然后调用这些 Promise 的数组。一旦传递数组中的每个 Promise 都解决了,就接受一个数组并返回一个解析。tweetsPromise.allPromise.allPromisesPromise

请注意,您当前似乎忽略了err可能返回的内容T.get-这可能不是一个好主意,最好能够检查何时发生错误,然后以某种方式处理错误(否则,tweetHold数组有时可能包含损坏的数据)。幸运的是,如果你使用 Promises,实现这一点很容易——只要rejecterr, 并且在 :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
  });

推荐阅读