我正在尝试使用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);
答案 0 :(得分:0)
T.get
接受一个回调函数,异步操作完成后将被调用。但是,由于您希望获得的是 multiple 响应,而不仅仅是一个响应,因此仅使用回调本身会有些混乱。例如,在returnedTweets
内,您可以增加一个持久计数器变量,然后一次counter === searchArray.users.length
调用下一个函数,但是改用Promises会更优雅。
将每个T.get
调用映射到一个Promise
解析的tweets
变量,然后在这些Promises数组上调用Promise.all
。 Promise.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
});