JavaScript promise绕过solve并继续.then()



我在嵌套承诺方面遇到了一些问题,导致忘记了承诺问题。

let promiseList = new Promise((resolve, reject) => {
//first query to retrieve from firebase
query.once( 'value', data => {
var promises = [];
data.forEach(snapshot => {
//get item key
//second query based on item key                                    
var promise = query.once('value');
promises.push(promise);
promise.then(data => { 
var itemDetail = data.val();
var receiptID = itemDetail.receiptID;
// third query to find matching receiptID
var query = firebase.database().ref('receipts');
query.once('value', data => {   
data.forEach(snapshot => {
snapshot.forEach(childSnapshot => {
if(childSnapshot.key == receiptID){
var branchDetail = childSnapshot.val().branch;
var branchName = branchDetail.branchName;
//console.log('inside promise ' + branchName);
datasetarr.push({branchName: branchName});
}
});
});
}); 
});
}); 
// wait till all promises are finished then resolve the result array
Promise.all(promises).then(() => resolve(datasetarr)); 
});             
});
// print out array here
promiseList.then((arr) => {
for(var i = 0; i < arr.length; i++){
console.log(arr[i].branchName);
}   
});

我设法从控制台打印出数据.log并带有"内部承诺"。但是,当我尝试从 .then(( 打印出来时,没有任何显示。

现在的问题是它实际上在我解决承诺之前先运行了 .then((。

有什么想法吗?

我从未使用过Firebase,但我知道承诺。 检查此示例链接承诺,注意生成链接的return语句。

var outerPromise = query.once('value').then(data => {
// Promise array to group 2nd level promises and then do a Promise.all.
var promises = [];
// This will be the main output of the outerPromise.
// We will populate it asynchronously inside our 2nd level promises.
var datasetarr = [];
data.forEach(snapshot => {
// 2nd level promises, will be appended to the promises array.    
// and will be enchained with the 3d level promise.
var promise = query.once('value').then(data => { 
var itemDetail = data.val();
var receiptID = itemDetail.receiptID;
var query = firebase.database().ref('receipts');
// Third level promise. It's enchained by the return statement.
return query.once('value').then(data => {   
data.forEach(snapshot => {
snapshot.forEach(childSnapshot => {
if(childSnapshot.key == receiptID){
var branchDetail = childSnapshot.val().branch;
var branchName = branchDetail.branchName;
//console.log('inside promise ' + branchName);
datasetarr.push({branchName: branchName});
}
});
});
}); 
});
promises.push(promise);
}); 
// We wait until 2nd (and third) level promises are ready
// and the return our desired output, the datasetarr
return Promise.all(promises).then(()=> datasetarr);
});             
// Since it's all chained, the outerPromise will resolve once all promises are completed
// and we can get the output we supplied in the last chaining.
outerPromise.then((arr) => {
console.log(arr)  
});

这不是承诺的运作方式,很少需要嵌套它们。如果query.once已经返回了一个很好的承诺,但除此之外,您需要包装它:

let returnsPromise = value => new Promise(res => query.once(value, data => res(data));

同样,如果它已经返回了一个不必要的承诺,但我不是火力基地的人。无论如何,现在您可以执行以下操作:

let result = returnsPromise('value')
// run secondary query based on item key
.then(data => Promise.all(data.map(item => returnsPromise(item.key)))
// now do stuff with those results
.then(data => {
return Promise.all(data.map(item => {
let receiptID = item.val().receiptID;
// Note that the same 'wrap if not already returning promise
// idea' is applicable here, but for illustration I'm just
// going to act like this returns a promise.
// Also note that while I've been rather down on nesting
// its more or less necessary here because you need to capture
// the receipt ID from the surrounding scope.
return firebase.database().ref('receipts')
.once('value')
.then(snapshot => {
return snapshot
.filter(x => x.key === receiptID)
.map(x => {
let branch = x.val().branch.branchName;
return {branch: branch};
});
});
}))
// Now we have an array of arrays of results but we want to
// remove the nesting.
.then(arrayOfArrays => arrayOfArrays.reduce((x,y) => { return x.concat(y); }, []));

现在,您有一个包含值数组的结果承诺。您可以调用then并迭代它:

result.then(arr => arr.forEach(x => console.log(x.branchName)));

最新更新