我正在通过我的Firebase应用程序在Firebase上获取某些数据。
我进行了三次检查,并调试了代码。第一次读取将返回数组中的5个项目。然后,我需要获取用户的ID并进行另一次提取,以从用户那里获取数据。这是我的代码:
export const fetchStyleItems = () => async dispatch => {
dispatch({ type: GET_STYLE_ITEMS_REQUEST });
database
.ref("styles_items")
.orderByChild("posted")
.once("value")
.then(function(snapshot) {
const exists = snapshot.val() !== null;
if (exists) data = snapshot.val();
var photo_feed = [];
for (var photo in data) {
const photoObj = data[photo];
database
.ref("users")
.child(photoObj.author)
.once("value")
.then(function(snapshot) {
const exists = snapshot.val() !== null;
if (exists) data = snapshot.val();
console.log(`inside the lasso ${photoObj} `);
photo_feed.push({
id: photo,
url: photoObj.url,
caption: photoObj.caption,
name: photoObj.name,
price: photoObj.price,
style_recomendation: photoObj.style_recomendation,
style_type: photoObj.style_type,
posted: photoObj.posted,
author: data.username
});
});
})
.catch(error => console.log(error));
}
console.log();
dispatch({
type: GET_STYLE_ITEMS_SUCCESS,
payload: photo_feed
});
})
.catch(error => console.log(error));
};
问题。当我调试代码并尝试调度GET_STYLE_ITEMS_SUCCESS时,数组photo_feed将为空。
我认为我在这里缺少一些范围。但是我现在停留了3个小时,看不到出了什么问题。
答案 0 :(得分:1)
我认为您是在for循环中迭代数组并进行异步调用,但您没有等待这些异步调用。因此,在您要调度数组时,photo_feed为空
具体在这里
for (var photo in data) {
const photoObj = data[photo];
database
.ref("users")
.child(photoObj.author)
.once("value")
.then(function(snapshot) {
// this is async
})
所以您应该等待这些承诺。此外,您的函数是异步的,但是您使用的是可链接的.then()
方法,而不是等待(这是添加异步的目的)。因此,我做了一些改写,并用var
let
export const fetchStyleItems = () => async dispatch => {
try {
dispatch({ type: GET_STYLE_ITEMS_REQUEST });
let snapshot = await database
.ref("styles_items")
.orderByChild("posted")
.once("value");
const exists = snapshot.val() !== null;
if (exists) {
data = snapshot.val();
}
let photo_feed = [];
for (let photo in data) {
const photoObj = data[photo];
let snapshot = await database
.ref("users")
.child(photoObj.author)
.once("value");
const exists = snapshot.val() !== null;
if (exists) {
data = snapshot.val()
};
photo_feed.push({
id: photo,
url: photoObj.url,
caption: photoObj.caption,
name: photoObj.name,
price: photoObj.price,
style_recomendation: photoObj.style_recomendation,
style_type: photoObj.style_type,
posted: photoObj.posted,
author: data.username
});
}
dispatch({
type: GET_STYLE_ITEMS_SUCCESS,
payload: photo_feed
});
}
catch (e) {
console.log(e);
}
};
我不确定100%等待for..in
是否可以正常工作(我相信可以);但是,如果没有,则可以用for..of
循环加上Object.keys(data)
答案 1 :(得分:0)
您的for循环正在对数据中的每张照片进行异步调用->在进行下一次调用以获取照片对象之前,您不必等待调用返回。您要获取第一个数据项的照片对象,然后在返回时获取下一个照片数据项的照片对象。
此代码导致了您的问题:
for (var photo in data) {
const photoObj = data[photo];
database
.ref("users")
.child(photoObj.author)
.once("value")
.then(function(snapshot) {
const exists = snapshot.val() !== null;
if (exists) data = snapshot.val();
console.log(`inside the lasso ${photoObj} `);
photo_feed.push({
id: photo,
url: photoObj.url,
caption: photoObj.caption,
name: photoObj.name,
price: photoObj.price,
style_recomendation: photoObj.style_recomendation,
style_type: photoObj.style_type,
posted: photoObj.posted,
author: data.username
});
});
})
.catch(error => console.log(error));
}
答案 2 :(得分:0)
由于结果是异步的,因此您需要等待结果分派。您可以将所有的Promise映射到一个数组,然后使用Promise#all。喜欢
const photoFeedPromises = data.map(photoObj => {
return database
.ref("users")
.child(photoObj.author)
.once("value")
.then(function(snapshot) {
const exists = snapshot.val() !== null;
if (exists) data = snapshot.val();
console.log(`inside the lasso ${photoObj} `);
return { snapshot }; // Or whatever you need
})
.catch(error => console.log(error));
});
Promise.all(photoFeedPromises).then(results => {
const photo_feed = results.filter(result => result !== undefined);
dispatch({
type: GET_STYLE_ITEMS_SUCCESS,
payload: photo_feed
});
});
您需要使用我发布的此代码段替换代码中的for
循环和对dispatch
的调用。