Я все еще работаю над лучшим пониманием обещаний.Я начал с некоторых образцов видео с обещаний Дуга Стивенсона на YouTube, а затем изменил его, чтобы использовать мои коллекции.Этот код больше всего напоминает образец с использованием областей и городов.
Вот код:
exports.getMatchesNew = functions.https.onCall((data, context) => {
console.log("In On Call", data);
return db.collection('matches').get()
.then(areaSnapshot => {
const promises = [];
areaSnapshot.forEach(doc => {
var area = doc.data();
// console.log("Area is ", area.mentees);
// console.log("area ID is ", area.id);
// Loop through each mentee for a mentor
for (const city in area.mentees)
{
// console.log("City is ", area.mentees[city]);
// User Information for current mentee
const p = db.collection('users').doc(area.mentees[city]).get();
//User Information for current mentor
const p2 = db.collection('users').doc(doc.id).get();
//console.log("Doc ",p);
// would like to combine this together, which will end up on one row
// mentor name, mentee name
promises.push(p, p2);
}
})
return Promise.all(promises);
//response.send(data);
})
.then(citySnapshots => {
const results = [];
citySnapshots.forEach(citySnap => {
const data = citySnap.data();
// this log entry is occuring once for each p and p2 from above.
// I tried an array reference like citySnap[0] for mentee info and citySnap[1] for mentor info, this did not work.
console.log("cSnap is: ", data);
results.push(data);
})
return Promise.all(results);
})
.catch(error => {
// Handle the error
console.log(error);
//response.status(500).send(error);
});
});
В результате получается, что я получаю имя и фамилию ученика, а затем вывод для имени и фамилии наставника (в отдельной строке).
В Firestore каждый документ в коллекции совпадений - это просто идентификатор наставника и массив идентификаторов ученика.Вся информация о пользователях хранится в коллекции пользователей.Итак, я пытаюсь пройтись по каждому документу на совпадения и создать один ряд данных для каждой комбинации наставник / ученик.
Мне все еще нужно добавить некоторую обработку, когда p и / или p2 недоступны.
Моим первоначальным намерением для 'p' и 'p2' было:
вернуть имя и фамилию для p, переименовать их в menteeFirstName и menteeLastName
вернуть имя и фамилию для p2, переименовать их mentorFirstname и mentorLastName
объединить эту информацию и вернуть массив mentorFirstName, mentorLastName, menteeFirstName, menteeLastName.
Однако я спустился в кроличью нору с этим.Я решил сократить его до рабочего кода и опубликовать это.
Итак, можно ли объединить данные из 'p' и 'p2'?Или я делаю это неправильно?
Я родом из реляционной базы данных, поэтому концепция коллекций / документов Firestore с асинхронными вызовами является для меня новой концепцией, с которой я становлюсь более знакомой (но не достаточнопока).
Я пытался понять различные примеры, но я думаю, что мое незнакомство с обещаниями сейчас является серьезным препятствием.Я испробовал и Roamer, и предложения Стивена Сарка.Предложение Роамера не ошибается, но я считаю, что оно отбрасывает обещания.
exports.getMatchesNew = functions.https.onCall((data, context) => {
return db.collection('matches').get()
.then(areaSnapshot => {
const promises = [];
areaSnapshot.forEach(doc => {
var area = doc.data();
for (let city in area.mentees) {
const p = db.collection('users').doc(area.mentees[city]).get();
const p2 = db.collection('users').doc(doc.id).get();
promises.push(
Promise.all([p, p2]) // aggregate p and p2
.then(([mentee, mentor]) => {
var mentorInfo = mentor.data();
var menteeInfo = mentee.data();
console.log("Mentor: ", mentorInfo.lastName);
console.log("mentee: ", menteeInfo.lastName);
// return a plain object with all the required data for this iteration's doc
return {
// 'area': area, // for good measure
// 'city': city, // for good measure
'mentee': menteeInfo, // ???
'mentor': mentorInfo // ???
};
})
);
}
})
return Promise.all(promises);
})
.catch(error => {
console.log(error);
//response.status(500).send(error);
});
});
Я вижу данные в журналах, но записи не возвращаются (или я неправильно ссылаюсь на них на странице .vue
<template slot="mentorLastName" slot-scope="row">
{{row.item.mentor.lastName}}
</template>
<template slot="menteelastName" slot-scope="row">
{{row.item.mentee.lastName}}
</template>
Это работает в других случаях, когда результаты содержат эти же объекты.
Код Стивена Сарка также выполняется на основе файлов журнала без ошибок. Разница в том, что страница vue никогда не возвращается (всегда отображается как «мышление»'). В прошлом это означало, что в облачной функции произошла ошибка. В журналах облачных функций нет ошибок, и данные НЕ отображаются в журналах консольной функции (тогда как в версии Roamer).Я не могу доказать, что работает.
exports.getMatchesNew = functions.https.onCall((data, context) => {
console.log("In On Call", data);
return db.collection('matches').get()
.then(areaSnapshot => {
const promises = [];
areaSnapshot.forEach(doc => {
var area = doc.data();
// console.log("Area is ", area.mentees);
// console.log("area ID is ", area.id);
// Loop through each mentee for a mentor
for (const city in area.mentees)
{
// console.log("City is ", area.mentees[city]);
// User Information for current mentee
const p = db.collection('users').doc(area.mentees[city]).get();
//User Information for current mentor
const p2 = db.collection('users').doc(doc.id).get();
//console.log("Doc ",p);
// would like to combine this together, which will end up on one row
// mentor name, mentee name
promises.push(p, p2);
}
})
return Promise.all(promises);
//response.send(data);
})
.then(citySnapshots => {
let mentee = citySnapshots[0];
let mentor = citySnapshots[1];
console.log("Mentor: ", mentor.lastName);
return {
mentee,
mentor
};
})
.catch(error => {
// Handle the error
console.log(error);
//response.status(500).send(error);
});
});
Я смотрю на оба этих измененных примера и чувствую, что понимаю их, а затем чмокаю себя, когда не получаю результатов.Я чувствую, что оба из них отбрасывают обещания, основанные на записях журнала, но я не понимаю, как.Мне кажется, что они связаны или связаны.Что никто не один.