[英]array push results in empty array javascript
我正在尝试将API结果存储到数组中。
数据显示在控制台中,但在将数据推入数组时,数组仍为空。
这是代码:
app.post('/fetchFavoriteTweets/', verifyToken, function(req, res) {
var favorites = [];
dbConn.then( function (database) {
var dbo = database.db("twitter_search");
dbo.collection('users').findOne(
{ _id: ObjectId(req.userId) }, function(err, result) {
if(err) throw err;
if(!result.hasOwnProperty('favorite_tweets')) {
res.status(404).json({msg:'record not found'});
}
else {
result.favorite_tweets.forEach(function (tweet) {
T.get('statuses/show', {id: tweet.id}, function(err, data, response) {
if(!err){
favorites.push(data);
console.log(data); //this returns data
} else {
console.log(err);
}
});
});
console.log(favorites);
// res.status(200).json({msg:'success', data:favorites});
}
});
}).catch(function(e){console.log(e)})
});
看起来您正在函数回调范围内定义favorites
数组。 尝试把var favorites = [];
在app.post()
之上调用。
另外,请记住,在回调完成后它只会有一个值,因此后面的任何同步代码只会看到空数组值。
我已经更新了你的代码,通过单独存储承诺并随后调用它来获取收藏:
UPDATE
正如你在演示中看到的那样,我在底部有2x console.log,第一个( C1 )包含在promise favoritesPromise ()
,第二个( C2 )包含在promise之后。 同步操作永远不会等待异步操作发生,因此在我的示例中, C2将始终在C1之前输出,即使console.log(1 ...)在console.log(2 ...)之前,它们也会在控制台中出现反转。
在promise中我添加了1ms的setTimeout
来模拟一个请求,它只需要实现当前输出。 你可以测试的另一件事是删除setTimeout
然后输出会改变一点,你的promise会变成同步,直到它达到resolve(favorites)
,这意味着favorites
现在拥有所有数据,但是当resolve
发生时,它变为异步,并且你的控制台你仍然会首先看到C2 (但现在有数据)和C1秒。
在我之前的回答中,我试图对你的代码实现这种推理。 保持它不同步的人!
var favorites = []; var favoritesPromise = () => { return new Promise((resolve, reject) => { console.log('Retrieving data from the internet.'); // This timeout mocks your request to anything that is async or promie setTimeout(() => { console.log('Request done') let resultFavorite_tweets = [{ id: 1, name: 'a dog' }, { id: 2, name: 'a cat' }]; resultFavorite_tweets.forEach(item => { favorites.push(item.name); }) resolve(favorites); // if you have an error use // reject(err) }, 1); }); } favoritesPromise().then(favList => { console.log(1, 'this will always contain data from the internet, but will always be last', favList); }) console.log(2, 'this will be empty (unless you remove setTimeout), but will always be first', favorites);
app.post('/fetchFavoriteTweets/', verifyToken, function(req, res) {
const favoritesPromise = () => {
return new Promise((resolve, reject) => {
var favorites = [];
dbConn.then(function(database) {
var dbo = database.db("twitter_search");
dbo.collection('users').findOne({
_id: ObjectId(req.userId)
}, function(err, result) {
if (err) reject(err);
if (!result.hasOwnProperty('favorite_tweets')) {
res.status(404).json({
msg: 'record not found'
});
} else {
result.favorite_tweets.forEach(function(tweet) {
T.get('statuses/show', {
id: tweet.id
}, function(err, data, response) {
if (!err) {
favorites.push(data);
console.log(data); //this returns data
} else {
console.log(err);
reject(err);
}
});
resolve(data);
});
console.log(favorites);
// res.status(200).json({msg:'success', data:favorites});
}
});
}).catch(function(e) {
reject(e)
})
});
}
// Here you call the promise to retrieve "favorites"
favoritesPromise().then(favoritesList => {
console.log('your favorites array', favoritesList)
})
})
尝试下一个代码
app.post('/fetchFavoriteTweets/', verifyToken, function (req, res) {
var favorites = [];
dbConn.then(function (database) {
var dbo = database.db("twitter_search");
dbo.collection('users').findOne(
{ _id: ObjectId(req.userId) }, function (err, result) {
if (err) throw err;
if (!result.hasOwnProperty('favorite_tweets')) {
res.status(404).json({ msg: 'record not found' });
}
else {
// Counter
let count = result.favorite_tweets.length;
result.favorite_tweets.forEach(function (tweet) {
T.get('statuses/show', { id: tweet.id }, function (err, data, response) {
// Decrease count
count -= 1;
if (!err) {
favorites.push(data);
// Check if count is zero
if (count === 0) {
console.log(favorites);
res.status(200).json({msg:'success', data:favorites});
}
} else {
console.log(err);
}
});
});
}
});
}).catch(function (e) { console.log(e) })
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.