我遇到了多层承诺的问题。我试图做的是首先得到某些类别下的收据项目清单,然后对于每个收据项目,我得到它的详细信息和收据ID,收到收据ID后,我搜索帐户ID。然后,我根据帐户ID获取帐户详细信息。这是我的代码:
button
我设法打印出上面button1.backgroundColor = UIColor.gray
button2.backgroundColor = UIColor.gray
的结果。但是,当我试图在这里打印时,承诺就完成了:
<div class="h3"><span class="glyphicon glyphicon-tags" aria-hidden="true"></span></div>
我什么都没得到。在我上面打印出的任何其他结果之前,控制台现在首先显示“承诺完成”。
有什么想法吗?先谢谢!
答案 0 :(得分:3)
我将在几个小时内提供更详细的解释,我之前已经参与,这意味着我现在无法提供详细信息
第一步到'#34; easy&#34;解决方案是创建一个函数,使一个数组从firebase快照中生成,因此我们可以使用map / concat / filter等
const snapshotToArray = snapshot => {
const ret = [];
snapshot.forEach(childSnapshot => {
ret.push(childSnapshot);
});
return ret;
};
现在,代码可以写成如下
// get list of receipt items under category
var query // = // get receipt items under certain category
var outerPromise = query.once('value').then(data => {
return Promise.all(snapshotToArray(data).map(snapshot => {
var itemData // = // get receipt item unique push ID
var query // = // get details of receipt items
return query.once('value').then(data => {
var itemDetail // = // get receipt item detail
if(type == subtype){
var receiptID = itemDetail.receiptID;
var query //= // query receipts table by receiptID
return query.once('value').then(data => {
return Promise.all([].concat(...snapshotToArray(data).map(snapshot => {
return snapshotToArray(snapshot).map(childSnapshot => {
if(childSnapshot.key == receiptID){
var accountKey //= // get accountID
var query //= // query accounts table
return query.once('value').then(data => {
var accountDetail = data.val();
var age = accountDetail.age;
var gender = accountDetail.gender;
console.log(age + ' ' + gender);
return({age, gender});
});
}
}).filter(result => !!result);
}).filter(result => !!result)));
});
}
});
})).then([].concat(...results => results.filter(result => !!result)));
});
在评论中解释问题
[].concat
用于将多个数组的内容添加到新数组中,即
[].concat([1,2,3],[4,5,6]) => [1,2,3,4,5,6]
...snapshotToArray(data).map(etc
...是扩展运算符,用作函数的参数,它采用可迭代和&#34;传播&#34;它到多个参数
console.log(...[1,2,3]) == console.log(1,2,3)
在这种情况下,snapshotToArray(data).map
返回一个数组数组,以提供控制台日志示例
console.log(...[[1,2],[3,4]]) == console.log([1,2], [3,4])
添加concat
[].concat(...[[1,2],[3,4]]) == [].concat([1,2],[3,4]) == [1,2,3,4]
因此它将两级数组展平为单一级别,即
console.log(...[[1,2],[3,4]]) == console.log(1,2,3,4)
总而言之,该代码片段的作用是扁平化两级数组
filter(result => !!result)
只需&#34;过滤器&#34;输出任何&#34; falsey&#34;的数组元素。因为你有这个条件
if(childSnapshot.key == receiptID){
如果这是假的,那么undefined
的结果将是map
- 所有其他结果将是一个数组,甚至空数组都是真的 - 这就是过滤完成的原因很经常!可能有更好的方法来完成所有这些,但除非你真的处理数百万件物品,否则过滤空结果并不是真正的问题
最终结果是一个平面数组,只有从
中的代码返回的Promises