【发布时间】:2019-04-18 05:50:00
【问题描述】:
我在 node.js 应用程序中有一个有效的递归函数,它使用带有 process.nextTick() 回调的 Promises。我很好奇这将/可能如何与异步等待一起工作。
我尝试了一些不同的方法,但无论我做了什么,异步函数都会在所有 nextTick 回调完成之前返回到调用函数。
不工作(删除从快速路由调用的缓存)
const deleteCache = async () => {
try {
const cacheRef = fsDb.collection('Cache');
return await deleteDocsBatch(cacheRef, 30);
} catch (e) {
console.error('error in deleteCache:' + e);
}
};
const deleteDocsBatch = async (cacheRef, batchSize) => {
try {
// get all the cached docs, limit to 30 to avoid potential memory issues
const snapShot = await cacheRef.limit(batchSize).get();
if (snapShot.size === 0) { return; }
const batch = fsDb.batch();
snapShot.docs.forEach((doc) => {
batch.delete(doc.ref);
});
await batch.commit();
process.nextTick(() => {
deleteDocsBatch(cacheRef, batchSize);
});
} catch (e) {
console.error('error in deleteDocsBatch:' + e);
}
};
工作:
function deleteCollection (batchSize) {
var collectionRef = fsDb.collection('Cache');
var query = collectionRef.orderBy('__name__').limit(batchSize);
return new Promise((resolve, reject) => {
deleteQueryBatch(fsDb, query, batchSize, resolve, reject);
});
}
function deleteQueryBatch (db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size === 0) {
return new Promise((resolve, reject) => { resolve(0); });
}
// Delete documents in a batch
var batch = db.batch();
snapshot.docs.forEach((doc) => {
batch.delete(doc.ref);
});
return new Promise((resolve, reject) => {
batch.commit().then(() => {
resolve(snapshot.size);
})
.catch(reject);
});
}).then((numDeleted) => {
if (numDeleted === 0) {
resolve();
return;
}
// Recurse on the next process tick, to avoid
// exploding the stack.
process.nextTick(() => {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
})
.catch(reject);
}
是否可以使用 async await 使用 nexttick() 编写此递归函数?
原始 Firestore 代码示例:
https://firebase.google.com/docs/firestore/manage-data/delete-data
【问题讨论】:
标签: node.js async-await lifecycle event-loop