Я конвертирую этот код из базы данных реального времени в Firestore.
Для создания некоторых заданий, которые будут обрабатываться позже, код проходит через каждого пользователя (документа) в Firestore, а затем через каждый документ из 2 вложенных подколлекций внутри каждого пользователя.
Я хочу, чтобы функция ожидала завершения каждого запроса, прежде чем завершить. Promise.all () всегда срабатывает после добавления трех обещаний, из которых первое не определено.
Я пытался использовать async / await, но в любом случае это не цель.
Я попытался создать отдельный массив обещаний только для самой вложенной логики (writeJobToBackLog ()).
Оба без успеха.
После нескольких часов игры я все еще не понимаю, что происходит, и мои навыки ведения журнала, вероятно, мешают мне получить более четкую картину.
Я не профессионал с обещаниями, но я немного поработал с ними, в основном с базой данных реального времени.
var database = admin.firestore();
// prepare()
test();
function test() {
console.log("prepare() called ...");
let promises = [];
database
.collection("users")
.get()
.then((snapshot) => {
snapshot.forEach((user) => {
user = user.data();
const userId = user.userId;
database
.collection("users")
.doc(userId)
.collection("projects")
.get()
.then((snapshot) => {
snapshot.forEach((project) => {
project = project.data();
const projectUrl = project.projectUrl;
const projectId = project.projectId;
database
.collection("users")
.doc(userId)
.collection("projects")
.doc(projectId)
.collection("subProjects")
.get()
.then((snapshot) => {
snapshot.forEach((subProject) => {
subProject.keywords.map(async (keyword) => {
let unreadyJob = {
keyword: keyword,
};
// returns a promise
let write = writeJobsToBackLog(unreadyJob);
writePromises.push(write);
return null;
});
return;
});
return;
})
.catch((error) => {
console.log(error);
})
return;
});
return;
})
.catch((error) => {
console.log(error);
})
});
return;
})
.catch((error) => {
console.log(error);
})
Promise.all(promises)
.then(() => {
console.log("prepare() finished successfully..." +
promises.map((promise) => {
console.log(promise);
return null;
}));
return null;
})
.catch((error) => {
console.log("prepare() finished with error: " + error + "...");
return null;
});
}
function writeJobsToBackLog(unreadyJob) {
console.log("writing job to Backlog ...");
return database
.collection("backLog")
.doc()
.set(unreadyJob);
}
Вот что выводится на консоль:
prepare() called ...
prepare() finished successfully...
writing job to Backlog ...
writing job to Backlog ...
writing job to Backlog ...
writing job to Backlog ...
(... more of those ...)
Все работает как положено, кроме логики Promise.all.
Я ожидаю, что он заполнит массив обещаний одним возвращенным обещанием для каждой записи, а затем подождет, пока все записи завершатся успешно.
Никакие обещания не добавляются в массив вообще.
Спасибо за любую помощь!
Итак, я изменил код:
async function test() {
console.log("prepare() called ...");
const users = await database.collection("users").get();
users.forEach(async (user) => {
const userId = user.data().userId;
const projects = await database
.collection("users")
.doc(userId)
.collection("projects")
.get();
projects.forEach(async (project) => {
const projectUrl = project.data().projectUrl;
const projectId = project.data().projectId;
const subProjects = await database
.collection("users")
.doc(userId)
.collection("projects")
.doc(projectId)
.collection("subProjects")
.get();
subProjects.forEach(async (subProject) => {
subProject.data().keywords.map(async (keyword) => {
let unreadyJob = {
keyword: keyword,
};
await writeJobsToBackLog(unreadyJob);
});
});
});
});
console.log("finished");
}
function writeJobsToBackLog(unreadyJob) {
console.log("writing job to Backlog ...");
return database
.collection("backLog")
.doc()
.set(unreadyJob);
}
Это дает тот же результат:
prepare() called ...
finished
writing job to Backlog ...
writing job to Backlog ...
writing job to Backlog ...
...
Что я делаю не так. Спасибо!