本文探討在使用async/await時,如何優雅地從異步回調函數中退出,尤其是在回調函數嵌套于async函數內部的情況。 這在使用MutationObserver監聽dom變化時尤其重要,需要精確控制回調函數的結束時機。
示例代碼中,函數a 使用傳統promise方式處理異步操作,而函數b 嘗試使用async/await簡化邏輯,避免Promise嵌套帶來的復雜性。 然而,直接在回調函數中使用return或break無法終止async函數的執行。
關鍵在于異步操作(例如MutationObserver)完成后,如何通知async函數繼續執行或退出。 有效的解決方案是利用Promise.withResolvers()。 此方法創建一個Promise,并提供resolve函數手動控制Promise的完成。 通過在回調函數中調用resolve(),可以通知async函數異步操作已完成,從而繼續執行后續操作或直接退出。
改進后的b 函數如下:
const b = async (): Promise<void> => { const { promise, resolve } = Promise.withResolvers<void>(); const callback = (mutations: MutationRecord[]) => { resolve(); }; const observer = new MutationObserver(callback); observer.observe(buttonEl, { attributes: true }); await p(); // 等待一個Promise函數執行完成 buttonEl.click(); // 觸發按鈕點擊事件 await promise; // 等待回調函數中的resolve() };
Promise.withResolvers() 創建一個Promise并返回其promise和resolve方法。 MutationObserver的回調函數調用resolve()完成此Promise。 async函數通過await promise等待Promise完成,從而控制執行流程。 需要注意的是,Promise.withResolvers()是較新的特性,需確保運行環境支持。
通過這種方法,我們可以在異步回調函數中精確控制async/await函數的執行,從而實現更優雅、更易維護的異步代碼。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END