Ключ состоит в том, чтобы разбить этот лог c на более мелкие, тестируемые, возвращающие обещания функции. Давайте начнем с checkAlreadyElementDB
// all the functions need this, move it to the top of the file
const db = firebase.firestore();
function checkAlreadyElementDB(appType, userID) {
return db.collection('#name')
.where('appType', '==', appType)
.where('userID', '==', userID).get().then(snapshot => {
return !snapshot.empty
})
}
Обратите внимание, как проверка может быть выполнена с помощью предложений where
в запросе. Это намного более быстрая операция, передающая клиенту гораздо меньше данных. Обратите также внимание на то, как эта и все другие функции возвращают обещания
Затем центру кода OP потребовалось немного усилий, чтобы распутать. Были вложенные обещания и имена, из-за которых было трудно следовать. Я приложил все усилия, чтобы понять, что имел в виду код, несмотря на то, что не очень понимал приложение.
function closeThenSetOrUpdate(doc) {
let data = doc.data()
// update the passed doc, no matter what the checkAlready... result is
return doc.ref.update({ open: false }).then(() => {
return checkAlreadyElementDB(data.appType, doc.id)
}).then(exists => {
if (data.open && !exists) {
console.log("Entered here: " + exists)
const newID = createRandomId()
return db.collection('#name').doc(newID).set({ #NotImportant })
} else {
return Promise.resolve() // just an empty promise
}
})
}
Вот функция, которая обрабатывает каждого пользователя, вызывая логи c выше. Обратите внимание, что он собирает обещания и выполняет их все вместе с Promise.all()
function updateANamesForUserWithID(userId) {
return db.collection('users').doc(userId).collection('#aName').get().then(snapshot => {
let promises = snapshot.docs.map(doc => {
return closeThenSetOrUpdate(doc)
})
return Promise.all(promises)
})
}
Теперь, базовую функцию проще написать, используя ту же технику Promise.all()
...
function triggerFunction(duration) {
return db.collection('users').get().then(snapshot => {
let promises = snapshot.docs.map(user => {
return updateANamesForUserWithID(user.id)
})
return Promise.all(promises)
}).then(() => {
setTimeout(triggerFunction, duration);
})
}