数组推送导致空数组javascript
我正在尝试将API结果存储到数组中 数据显示在控制台中,但将数据推入数组时,数组仍然为空 代码如下:数组推送导致空数组javascript,javascript,node.js,rest,api,Javascript,Node.js,Rest,Api,我正在尝试将API结果存储到数组中 数据显示在控制台中,但将数据推入数组时,数组仍然为空 代码如下: app.post('/fetchFavoriteTweets/', verifyToken, function(req, res) { var favorites = []; dbConn.then( function (database) { var dbo = database.db("twitter_search"); dbo.coll
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)})
});
看起来您正在函数回调的范围内定义
收藏夹
数组。尝试放置var收藏夹=[]代码>在你上方app.post()
调用
另外,请记住,它只有在回调完成后才会有一个值,因此后续任何同步代码都只会看到空数组值。我已经更新了您的代码,通过单独存储承诺并在以后调用它来获取收藏夹:
更新
正如您在演示中看到的,我在底部有2个console.log,第一个(C1)包含在promisefavoritesPromise()
中,第二个(C2)位于promise之后。
同步操作永远不会等待异步操作发生,因此在我的示例中,C2将始终在C1之前输出,即使console.log(1…)在console.log(2…)之前,它们在控制台中的显示也会相反
在promise中,我添加了1ms的setTimeout
来模拟请求,这是实现当前输出所需的全部。您可以测试的另一件事是删除设置超时
,然后输出将发生一些变化,您的承诺将变为synchronus,直到它达到解析(收藏夹)
,这意味着收藏夹
现在已拥有所有数据,但当发生解析
时,它将变为异步,在您的控制台中,您仍将首先看到C2(但现在有数据),然后看到C1
在我之前的回答中,我尝试将此推理应用到您的代码中。
保持异步,伙计们强>
var收藏夹=[];
var-favoritesPromise=()=>{
返回新承诺((解决、拒绝)=>{
log('从internet检索数据');
//此超时将模拟您对任何异步或promie的请求
设置超时(()=>{
console.log('请求完成')
让resultFavorite_tweets=[{
id:1,
名字:“一只狗”
}, {
id:2,
名字:“一只猫”
}];
resultFavorite_tweets.forEach(项目=>{
收藏夹.推送(项目.名称);
})
解决(收藏夹);
//如果您有错误,请使用
//拒绝(错误)
}, 1);
});
}
favoritesPromise()。然后(favList=>{
日志(1,“这将始终包含来自internet的数据,但始终是最后一个”,favList);
})
日志(2,“这将是空的(除非您删除setTimeout),但始终是第一个”,收藏夹)代码>尝试下一个代码
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) })
});
如果您试图访问承诺之外的收藏夹
,则它是空的,因为承诺尚未兑现,您应该将其作为回调或异步/等待promise@darklightcode你能把这个作为一个答案吗?@Azima-和你下面的答案差不多。我现在得到了以下错误:E:\twitter\u search\u backend\node\u modules\mongodb\lib\utils.js:132
throw err
^
引用错误:在E:\twitter\u search\u backend\app.js:243:23
在Array.forEach()
@Azima try and comment拒绝(err)
从T.get('statuses/show')
回调中定义数据,因此错误是不言自明的(您是否在数据中得到响应,它是否显示在console.log中?)