[英]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.