Devuelva todos los documentos cuando todos los documentos se eliminen de una colección en Firestre

Estoy usando el siguiente código para eliminar todos los documentos de una colección en Firestre. Mi pregunta es, ¿cómo ejecutar una función que devolverá el resultado (promesa) de ‘deleteCollection’ entre una matriz con los documentos eliminados? Quiero recorrer todos los documentos. Seguramente puedo consultar todos los datos primero, recorrerlos y ejecutar esta función, pero luego los datos se leen dos veces.

Otra opción sería crear una variable global vacía en la que la función de eliminación agrega el documento. ¿Pero qué tan seguro es esto? Si estoy eliminando dos colecciones enormes, la matriz se rellena con dos documentos diferentes. Eso tampoco sería correcto.

También intenté modificar la devolución de ‘nueva Promesa’, pero los parámetros de la función solo pueden contener resolución o rechazo, no matrices.

Así que quiero una función que llame a deleteCollection y que quiera recorrer los datos eliminados. ¿Es esto posible cuando quiero leer los datos una sola vez?

function deleteCollection(db, collectionRef, batchSize) { var query = collectionRef.limit(batchSize); return new Promise(function(resolve, reject) { deleteQueryBatch(db, query, batchSize, resolve, reject); }); } function deleteQueryBatch(db, query, batchSize, resolve, reject) { query.get() .then((snapshot) => { if (snapshot.size == 0) { return 0; } var batch = db.batch(); snapshot.docs.forEach(function(doc) { batch.delete(doc.ref); }); return batch.commit().then(function() { return snapshot.size; }); }).then(function(numDeleted) { if (numDeleted <= batchSize) { resolve(); return; } process.nextTick(function() { deleteQueryBatch(db, query, batchSize, resolve, reject); }); }) .catch(reject); } 

Editado de la respuesta de Bergi.

 const results = deleteCollection(db, db.collection("deleteme"), 1) //Now I want to work with the results array, //but the function is still deleting documents function deleteCollection(db, collectionRef, batchSize) { return deleteQueryBatch(db, collectionRef.limit(batchSize), batchSize, new Array()); } async function deleteQueryBatch(db, query, batchSize, results) { const snapshot = await query.get(); if (snapshot.size > 0) { let batch = db.batch(); snapshot.docs.forEach(doc => { results.push(doc); = batchSize) { return deleteQueryBatch(db, query, batchSize); } else { return results; } } 

En primer lugar, evite el constructor Promise antipattern :

 function deleteCollection(db, collectionRef, batchSize) { var query = collectionRef.limit(batchSize); return deleteQueryBatch(db, query, batchSize); } function deleteQueryBatch(db, query, batchSize) { return query.get().then(snapshot => { if (snapshot.size == 0) return 0; var batch = db.batch(); snapshot.docs.forEach(doc => { batch.delete(doc.ref); }); return batch.commit().then(() => snapshot.size); }).then(function(numDeleted) { if (numDeleted >= batchSize) { // I don't think process.nextTick is really necessary return deleteQueryBatch(db, query, batchSize); } }); } 

(Es posible que también desee utilizar la syntax async / await que realmente simplifica el código y hace que el algoritmo sea más comprensible:

 async function deleteQueryBatch(db, query, batchSize) { const snapshot = await query.get(); if (snapshot.size > 0) { let batch = db.batch(); snapshot.docs.forEach(doc => { batch.delete(doc.ref); }); await batch.commit(); } if (snapshot.size >= batchSize) { // await new Promise(resolve => process.nextTick(resolve)); return deleteQueryBatch(db, query, batchSize); } } 

creando una variable global vacía en la que la función de eliminación agrega el documento. ¿Pero qué tan seguro es esto? Si estoy eliminando dos colecciones enormes, la matriz se rellena con dos documentos diferentes. Eso tampoco sería correcto.

No, no hagas esto. Simplemente pase la matriz que está rellenando con los resultados como un argumento a través de las llamadas recursivas y devuélvala al final:

 function deleteCollection(db, collectionRef, batchSize) { return deleteQueryBatch(db, collectionRef.limit(batchSize), batchSize, []); } async function deleteQueryBatch(db, query, batchSize, results) { const snapshot = await query.get(); if (snapshot.size > 0) { let batch = db.batch(); snapshot.docs.forEach(doc => { results.push(doc); batch.delete(doc.ref); }); await batch.commit(); } if (snapshot.size >= batchSize) { return deleteQueryBatch(db, query, batchSize, results); } else { return results; } } 
Intereting Posts