为何函数不等待Promise解析?如何确保异步调用完成后取值
问题:确保异步调用完成后获取布尔值
原代码示例
checkout.ts
renderButton(){ renderShadowDomButton(); let globalValue = getGlobalValue() }
web_component_render.ts
let globalValue; async asyncFunction() { let booleanFromAsync = await someExternalAPICall(); return booleanFromAsync; } function renderShadowDOMButton() { asyncFunction.then((booleanFromAsync) => { globalValue = booleanFromAsync; }) } export function getGlobalValue() { return globalValue; }
问题原因
当前代码里,renderButton调用renderShadowDomButton后会立刻执行getGlobalValue,但asyncFunction是异步操作,.then里的赋值逻辑会被放进微任务队列,要等当前同步代码执行完才会触发。所以getGlobalValue拿到的是还没更新的初始值,异步调用完成后才会修改globalValue。
解决方案
方案1:让渲染函数返回Promise,用async/await等待完成
修改web_component_render.ts中的renderShadowDOMButton,让它返回Promise:
function renderShadowDOMButton() { // 返回asyncFunction的Promise链 return asyncFunction().then((booleanFromAsync) => { globalValue = booleanFromAsync; }) }
然后将checkout.ts中的renderButton改为异步函数,用await等待渲染完成后再取值:
async renderButton(){ await renderShadowDomButton(); let globalValue = getGlobalValue(); // 此处可安全使用更新后的globalValue }
方案2:让取值函数直接返回异步结果(去掉全局变量)
如果不需要全局变量存储结果,可以直接让getGlobalValue返回异步调用的Promise:
// web_component_render.ts async asyncFunction() { let booleanFromAsync = await someExternalAPICall(); return booleanFromAsync; } function renderShadowDOMButton() { return asyncFunction().then((booleanFromAsync) => { // 在这里处理按钮渲染逻辑,比如根据booleanFromAsync调整样式 }) } export async function getGlobalValue() { return await asyncFunction(); }
在checkout.ts中直接等待取值结果:
async renderButton(){ await renderShadowDomButton(); // 可选:如果需要先完成渲染再取值 let globalValue = await getGlobalValue(); }
方案3:使用回调函数通知结果
修改renderShadowDOMButton,接受一个回调函数,在异步完成后触发:
// web_component_render.ts function renderShadowDOMButton(onComplete: (value: boolean) => void) { asyncFunction().then((booleanFromAsync) => { globalValue = booleanFromAsync; onComplete(booleanFromAsync); }) }
在checkout.ts中通过回调获取结果:
renderButton(){ renderShadowDomButton((booleanFromAsync) => { // 异步完成后执行这里的逻辑 let globalValue = getGlobalValue(); // 或者直接使用booleanFromAsync参数 }); }
内容的提问来源于stack exchange,提问作者shailesh
相关产品推荐
相关产品推荐

