如何用async/await实现代码等待?优化嵌套Promise的初始化函数
如何让嵌套Promise的init函数执行完毕后再执行后续代码?
问题场景
原代码用嵌套Promise写了init函数,用来测试async/await:
function init() { console.log(1) accountsStore.getAccounts().then(() => { categoriesStore.getCategories().then(() => { sheetItemStore.getSheetItems().then(() => { accountsStore.getTotal().then(() => { sheetItemStore.getTotals().then(() => { balanceStore.getGrandTotal().then(() => { console.log(8) }) }) }) }) }) }) console.log(9) }
所有异步函数的结构如下(以getAccounts为例):
async function getAccounts() { let response = await axios.get(route('accounts.index', {'id': baseStore.balance.id})) accounts.value = response.data console.log(2) }
现在控制台输出顺序是1、9、2、3、4、5、6、7、8,需要让init内所有异步函数执行完成后,再执行后续代码(比如视图渲染)。
解决方案
核心是用async/await替代嵌套Promise的then调用,让异步代码以同步写法执行,同时让init本身返回Promise,方便后续等待它完成。
1. 把init改成async函数,顺序执行异步任务
将init声明为async函数,用await依次等待每个异步函数完成,这样所有异步任务会按顺序执行完,再走后续代码:
async function init() { console.log(1) // 依次等待每个异步函数执行完成 await accountsStore.getAccounts(); await categoriesStore.getCategories(); await sheetItemStore.getSheetItems(); await accountsStore.getTotal(); await sheetItemStore.getTotals(); await balanceStore.getGrandTotal(); console.log(8) console.log(9) // 现在9会在所有异步任务完成后执行 }
2. 等待init完成后再渲染视图
在调用init的地方,同样用await等待它执行完毕,再写视图渲染逻辑:
// 示例:在启动逻辑里调用 async function startApp() { await init(); // 这里编写视图渲染代码 console.log('所有异步任务完成,开始渲染视图'); } startApp();
3. 优化:并行执行无依赖的异步任务
如果部分异步函数之间没有依赖关系(比如getCategories不需要等getAccounts完成),可以用Promise.all并行执行这些任务,提升效率:
async function init() { console.log(1) // 并行执行无依赖的异步任务,同时等待全部完成 await Promise.all([ accountsStore.getAccounts(), categoriesStore.getCategories(), sheetItemStore.getSheetItems() ]); // 执行有依赖的后续异步任务 await accountsStore.getTotal(); await sheetItemStore.getTotals(); await balanceStore.getGrandTotal(); console.log(8) console.log(9) }
原问题原因
原代码里,嵌套的then调用属于异步任务,会被放到浏览器事件队列里排队,而同步代码console.log(9)是立即执行的,所以先输出1、9,之后异步任务才会依次完成输出2-8。用async/await可以让异步任务按顺序阻塞执行,确保所有异步操作完成后再走后续代码。
内容的提问来源于stack exchange,提问作者Ivar
相关产品推荐
相关产品推荐

