我有一个主要功能,可以等待并并行连接几个功能,如下所示:
主要功能:
console.log('A');
const pivotData = await Promise.all(
Object.entries(thenWidgets.val()).map(widget => {
getPivot(widget, userId)
console.log('B');
});
);
console.log('C');
console.log('D');
const mainData = await Promise.all(
pivotData.map(widget => getMain(widget))
);
console.log('F');
mainData.map(item => {
return (finalObject[item.widgetId] = item);
});
console.log('G');
在到达console.log('D')
以下的mainData之前,该工作正常。似乎不等待诺言就跳到console.log('F')
而不等待拥有console.log('E')
的getMain函数
getMain()函数:
const getMain = widget => {
return new Promise(resolve => {
var requests = [];
const pivotData = {};
Object.keys(widget.pivot).map(item => {
const mainRef = firebase
.database()
.ref()
.child(widget['default'].type)
.child(item);
mainRef.once('value', snapMain => {
pivotData[item] = snapMain.val();
}).then(() => {
widget['main'] = pivotData;
console.log('E');
requests.push('test');
});
console.log('E2')
})
Promise.all(requests)
.then(() => {
console.log('E3');
resolve(widget);
})
.catch(error => console.log(`Error in promises ${error}`));
});
};
这里的预期结果是:“ E,E2,E,E2,E3”,但是我得到的是“ E2,E2,E3”,然后它返回了承诺。后来,在所有诺言解决之后,我得到了“ E,E”。所以整个事情的预期结果应该是“ A,B,C,D,E,E2,E,E2,E3,F,G”,我现在是“ A,B,C,D,E2,E2 ,E3,F,G,E,E'
似乎Object.keys
中getMain()
内部的诺言没有等待mainRef.once
。也许我缺少了一些东西。
我的问题是:诺言没有等待getMain()
函数,这出了什么问题?
答案 0 :(得分:1)
让我们仔细看一下getMain函数,特别是console.log('E')
周围的行。以下是发生的情况:
.once(...)
返回的不是await
的承诺,因此稍后{em {em}之后 {em}返回getMain
进行承诺,因此要执行的下一行是await
,然后在循环的下一次迭代中进行console.log('E2')
将是一个空数组(因为期望值来自requests
处理程序,但我们从未等待过这些诺言)。空数组立即得到解析,因此.once(...)
进入Promise.all(requests)
部分,注销“ E3”并解析主要承诺,有效地返回了原始小部件then
返回,我们先前创建的Promise将开始解析和修改“幕后”窗口小部件,因此下次您尝试对窗口小部件执行任何操作时,您可能会发现完全出乎意料的事情。 / li>
要修复此功能,您需要先等待Firebase返回的承诺,然后再进入底部的主要承诺-您可以通过将{{1 }}调用一个新数组,并在该数组上getMain
,或者通过在每次循环迭代中编写一个“链式” promise,然后在循环之后立即等待它
希望有帮助!