响应式系统处理 promise 异步返回的核心是保持 ui 可响应、不卡顿、不白屏;需提前声明响应式字段并设合法初始值,用 loading 状态接管等待期,await 所有异步调用,嵌套 map 前加空值防护。

响应式系统处理 Promise 异步返回,核心不是“等 Promise 完成再渲染”,而是让 UI 在 Promise 生命周期中保持可响应、不卡顿、不白屏。所谓“先渲染后赋值”的白屏坑,本质是把异步数据加载和视图挂载强行耦合——比如在 data 初始化时留空字段却没设默认值,或在生命周期里忘了控制 loading 状态,导致 DOM 已挂载但内容始终为空,用户看到一片空白。
确保响应式字段提前声明且有合法初始值
Vue(尤其 Vue 2)对新增属性不做响应式代理。若 data 返回对象里漏写字段,后续用 this.list = res.data 赋值可能不触发更新;更糟的是写成 list: undefined,配合 v-if="list.length" 就会因 undefined.length 报错中断渲染。
- ✅ 正确做法:data 中显式初始化为 []、null 或 {},而非 undefined
- ✅ 接口返回后,只给已声明字段赋值,不动态添加新 key
- ✅ 模板中用 v-if="Array.isArray(list) && list.length" 替代模糊判断
用 loading 状态接管“等待期”,避免视觉断层
白屏常不是没数据,而是没反馈。用户点击进入页面,JS 已执行、DOM 已生成,但因为没设 loading,也没 fallback 内容,界面静默几秒,就以为卡死或失败了。
- ✅ 在 onLoad 或 mounted 开始时设 this.loading = true
- ✅ Promise 的 .finally(() => this.loading = false) 统一收尾,无论成功失败都关闭 loading
- ✅ 模板中用 v-if="loading" 渲染骨架屏 / v-else 展示真实内容,不依赖数据是否为空
Promise 链要 await 到底,别在 onLaunch/onShow 里丢弃它
uni-app 白屏高频原因是 App.vue 的 onLaunch 里写了 uni.getStorage({key:'token'}) 却没加 await。这不会报错,但 JS 线程会被阻塞,Vue 实例根本挂载不上——连 loading 都没机会显示。
- ✅ 所有异步调用必须 await,包括 uni.getSystemInfo、uni.getStorage、uni.request
- ✅ 耗时同步操作(如大 JSON.parse、正则全文匹配)一律移出 onLaunch,改用懒加载或分片处理
- ✅ 真机调试时打开 Network 面板,确认 app-service.js 是否加载成功——404 或超时也会白屏
避免嵌套 map 渲染引发的崩溃型白屏
React/Vue 中常见错误:list.map(item => item.children.map(...))。一旦某 item.children 是 undefined,就会抛 Cannot read property 'map' of undefined,整个组件渲染中断,页面变白。
- ✅ 外层 map 前加空值防护:list?.map 或 Array.isArray(list) && list.map
- ✅ 内层 map 前校验:item.children?.map,不假设结构一定存在
- ✅ 每个 map 生成的元素必须带 key,且 key 值稳定唯一,不能用 index 当 key 处理深层嵌套











