我是使用JavaScript的Firebase新手,我知道我可以使用检索数据的输出返回一个promise。但在下列情况下,我无法真正看到它:
filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => {
const TOTAL_SCORE = 100;
var matches = {}; // Matches to be stored in the database
potentialMatches.forEach(user => {
if (user.val() !== userID) {
databaseRef.child(`users/${user.val()}/profile`).once("value", (snapshot) => {
const matchScore = calculateMatchScore(userProfile, snapshot.val(), maxDistanceToSearchForMatches);
//console.log("final score is " + matchScore);
if (matchScore) {
const match = {
compatibility: matchScore / TOTAL_SCORE,
distance: distance,
profile: snapshot.val()
}
matches[user.val()] = match;
}
});
}
});
};
我在迭代用户' ID和访问其配置文件以进行一些计算,并将结果及其配置文件添加到对象。
如何在所有用户完成后返回一个promise对象对象?
答案 0 :(得分:1)
.once()
返回一个承诺。
您可以使用Promise.all()。 Promise.all()获取一个promises数组作为参数,它返回一个promise,它将在所有传递的promises解析时解析。
修改后的代码如下所示:
filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => {
var matches = {}; // Matches to be stored in the database
const promisesList = [];
potentialMatches.forEach(user => {
if (user.val() !== userID) {
// save a reference to the promise
const dataPromise = databaseRef.child(`users/${user.val()}/profile`).once("value", (snapshot) => {
// ...
});
// push the promise in the promise list
promiseList.push(dataPromise);
}
});
return Promise.all(promisesList).then(() => Promise.resolve(matches));
};
即使列表中的某个承诺被拒绝,您也可能希望解决。 您可以执行以下操作,处理被拒绝的承诺。
promiseList.push(
// have to handle the reject
dataPromise
.then(data => data)
// returns a resolved promise with { error } object.
// doing this Promise.all() will always resolve even if some of them are rejected.
.catch(error => {
return { error: error };
})
);
答案 1 :(得分:0)
您可以创建一个在完成配置文件迭代时使用matches
对象解析的promise。注意我没有处理错误
filterUsersAndCalculateMatches = (userProfile, userID, potentialMatches, maxDistanceToSearchForMatches) => {
//Return a new promise
return new Promise((resolve, reject) => {
const TOTAL_SCORE = 100;
var matches = {}; // Matches to be stored in the database
var promises = []; // create an array for promises during iteration over profiles
potentialMatches.forEach(user => {
if (user.val() !== userID) {
// Save promise in var p
var p = databaseRef.child(`users/${user.val()}/profile`).once("value").then((snapshot) => {
const matchScore = calculateMatchScore(userProfile, snapshot.val(), maxDistanceToSearchForMatches);
//console.log("final score is " + matchScore);
if (matchScore) {
const match = {
compatibility: matchScore / TOTAL_SCORE,
distance: distance,
profile: snapshot.val()
}
matches[user.val()] = match;
}
});
promises.push(p);
}
});
Promise.all(promises).then(resolve.bind(resolve, matches));
});
};