Svelte await块内变量如何在script块中存储引用
Svelte {#await}块获取Promise结果引用的实现方案
两种临时方案都属于冗余实现,Svelte本身的响应式机制完全可以用更简洁的写法满足需求,不需要hack模板逻辑,也不用放弃{#await}自带的加载/错误态处理能力。
最推荐写法:逻辑全收敛到Script块
所有数据处理逻辑放在<script>中,模板只负责渲染,是Svelte官方推荐的分层方式,兼容Svelte3/4/5全版本:
<script> // 原有请求Promise let myPromise = fetchTableData() // 存储结果和需要单独操作的字段 let myResult = null let rowsInScript = null // 响应式追踪Promise状态,resolve后自动执行赋值逻辑 $: myPromise?.then(res => { myResult = res rowsInScript = res.rows // 所有需要操作结果的逻辑都可以写在这里 // 后续需要更新rows直接修改rowsInScript即可,响应式会自动同步到视图 }) </script> <!-- 模板正常使用{#await}处理三态渲染,无任何逻辑侵入 --> {#await myPromise} <LoadingSkeleton /> {:then myResult} <DataTable rows={myResult.rows}/> {:catch err} <ErrorTip message={err.message} /> {/await}
这种写法的额外优势是后续需要重新拉取数据时,只需要给myPromise赋值新的Promise实例,上面的响应式逻辑会自动重新执行,不需要额外绑定刷新触发逻辑。
轻量Hack写法(无额外函数定义)
如果就是想在模板内直接完成赋值,不需要单独抽逻辑,也不用定义冗余的包装函数,用JS逗号表达式就能实现和空函数方案一样的效果,代码更简洁:
{#await myPromise then myResult} <!-- 逗号表达式先执行赋值,最终返回空字符串,不会渲染任何内容 --> {(rowsInScript = myResult.rows, '')} <DataTable rows={myResult.rows}/> {/await}
注意这种写法每次组件重渲染都会执行赋值,如果赋值逻辑比较重,还是推荐用上面script块响应式监听的方案。
原有方案的问题
- 全写
fetch().then()的方案:需要手动维护加载中、加载失败、加载完成三个状态,等于重复实现了一遍{#await}块的内置能力,代码冗余度高。 - 空包装函数的方案:属于无意义的抽象hack,后续维护的开发者无法第一时间理解这个函数的作用,代码可读性差。
内容的提问来源于stack exchange,提问作者Ian Marteens
相关产品推荐
相关产品推荐

