我声明了一个使Firebase数据异步的函数。该功能必须等待,直到所有数据都放入对象内。由于某些原因,该功能可以继续运行而无需等待对象已设置。
/** Get the data content */
const getData = async (widget, userId) => {
let promises = [];
let mainObject = {};
const pivotData = {};
const pivotName =
'user' + widget[1].type.charAt(0).toUpperCase() + widget[1].type.slice(1);
//Object entries
mainObject = {
default: widget[1],
};
mainObject['widgetId'] = widget[0];
//Main listner
const mainRef = firebase
.database()
.ref()
.child(widget[1].type);
//Pivot Listner
const pivotRef = firebase
.database()
.ref()
.child(pivotName)
.child(userId);
//Set promise
promises.push(
new Promise(async resolve => {
pivotRef
.once('value', snapPivot => {
snapPivot.forEach(function(result) {
if (result.val().widgetId === widget[0]) {
pivotData[result.key] = result.val();
mainObject['pivot'] = pivotData;
mainObject['typeId'] = result.key;
mainObject['main'] = {};
console.log('1');
mainRef.child(result.key).once('value', snapshot => {
console.log('2');
mainObject['main'][result.key] = snapshot.val();
});
}
});
})
.then(() => {
resolve();
console.log('3');
});
})
);
Promise.all(promises).then(results => {
return mainObject;
});
};
console.logs的预期结果为1,2,3,但显示为1,1,3,2
为什么函数不等待循环内的.once
函数?
答案 0 :(得分:0)
问题是您没有等待mainRef.child(result.key).once()的承诺解决。
另外,您只将一个promise推送到您的promise数组中,而您希望在调用mainRef.child(result.key).once()时兑现您获得的promise。
使用await Promise.all()
see MDN。
// Reference.once returns a promise Promise<DataSnapshot>
const dataSnapshot = await pivotRef.once('value');
let promises = [];
dataSnapshot.forEach((result) => {
const key = result.key;
const data = result.val();
if (data.widgetId === widget[0]) {
pivotData[key] = data;
mainObject['pivot'] = pivotData;
mainObject['typeId'] = key;
mainObject['main'] = {};
console.log('1');
const promise = mainRef.child(result.key)
.once('value', snapshot => {
console.log('2');
mainObject['main'][result.key] = snapshot.val();
});
// add promise to our promises array
promises.push(promise);
}
});
// wait for all the promises to be fulfilled (i.e resolved)
await Promise.all(promises);
// assuming 3 only needs to be logged once (at the end)
console.log('3');
console.log(mainObject);
return mainObject;
让我知道这是否有效!