如何确保IndexedDB缓存失效函数中嵌套Promise完成后执行后续函数
Hey,我看到你的问题了——你想让invalidateCache()返回的Promise在所有第二层的缓存检查和删除操作都完成后,再触发后续的.then()回调对吧?
问题出在你当前的代码里:外层的.then()只等待了keys(cacheStore)完成,但并没有等待keys.map()里生成的所有第二层Promise执行完毕。所以当你调用this.invalidateCache().then(...)时,后续函数会在第一个Promise完成后立刻跑起来,而不是等所有缓存操作都做完。
给你调整后的代码,保证所有异步操作都完成后才resolve外层Promise:
invalidateCache() { let now = Date.now() return keys(cacheStore).then((keys) => { // 用Promise.all等待所有map出来的Promise全部完成 return Promise.all(keys.map((key) => { return this.getCachedResponse(key).then((item) => { if (item.expire < now) { // 如果deleteCache是异步的,一定要return它,确保这个Promise等待删除完成 return this.deleteCache(key) } }) })) }).catch((err) => { console.error(err) // 重新抛出错误,让后续链式调用的.catch()也能捕获到 throw err; }) }
关键修改点:
Promise.all():把keys.map()生成的Promise数组传给它,这样外层的.then()会等待所有这些Promise都resolve后才会完成。- 返回
deleteCache的Promise:如果deleteCache是异步函数(比如返回Promise),一定要return它,这样每个单独的Promise会等待删除操作完成,不会漏掉任何一步。 - 重新抛出错误:在catch里抛出错误,这样后续链式调用的
.catch()也能捕获到这个错误,而不是只在内部打印。
如果你用的环境支持ES6+的async/await,可以写成更易读的版本:
async invalidateCache() { try { const now = Date.now() const keys = await keys(cacheStore); // 等待所有缓存检查和删除操作完成 await Promise.all(keys.map(async (key) => { const item = await this.getCachedResponse(key); if (item.expire < now) { await this.deleteCache(key); } })); } catch (err) { console.error(err); throw err; } }
这个版本用async/await让代码逻辑更线性,可读性更高,和Promise链式写法的效果完全一致。
现在你再调用this.invalidateCache().then(() => { /* 这里的代码会在所有缓存操作完成后执行 */ })就没问题啦!
内容的提问来源于stack exchange,提问作者ctf0
相关产品推荐
相关产品推荐

