功能及問題
如下代碼,
使用用戶最后一次配置信息的同時,當用戶關閉數據記錄時提示用戶確定關閉。
export default {
name: 'editPage',
data() {
return {
page: {},
fpSettings: {},
settingApiOk: false,
}
},
watch: {
fpSettings: {
handler(newVal) {
let pageSettings = this.page.settings || {}
if(this.settingApiOk && newVal.trace === false && pageSettings.trace === true) {
this.$dialog.confirm({
message: '確定關閉嗎?',
cancelButtonText: '暫不',
confirmButtonText: '確定',
}).then(() => {
console.log('確定')
}).catch(() => {
console.log('暫不')
newVal.trace = true
})
}
this.page.settings = {...pageSettings, ...newVal}
},
deep: true,
},
},
mounted() {
http.get(`fppage/lastSetting`).then(({ settings: lastSettings } = {}) => {
http.get(`fppage/setting`).then((settings = {}) => {
this.fpSettings = Object.assign(this.fpSettings, lastSettings, settings.settings)
this.settingApiOk = true
})
})
}
}
現在有一個 bug , 在手機上, 如果選項為關閉, 刷新時會直接彈出提示窗口, 正確情況是只應該在用戶設置的時候彈出。在電腦上把網速調為 Fast 3G
以下會重現。
經測試, 如果不使用 fppage/lastSetting
這個請求直接是正常的。
但 setting
是寫在 lastSetting
的回調 then
中的, 應該他兩不存在干擾問題呀。
但還是猜想有沒有可能雖然寫了 then
,他們依然可能同時發出請求, 同時接收到數據。
並且使用了一個 settingApiOk
變量來判斷接口是否請求完成, 然而問題依舊。
改為同步方式
試圖使用 async / await
異步轉為同步的方法, 把 mounted
中的代碼抽取 methods
中。
貌似與之前的代碼也沒什么不同。確實, 問題依舊。
逐步 debugger
, 確定是一個接口一個接口的請求完, 代碼一行一行的走的哇。
async intSetting () {
const lastSettings = await this.$http.get(`fppage/lastSetting`)
const setting = await this.$http.get(`fppage/setting`)
this.fpSettings = Object.assign(this.fpSettings, lastSettings, setting.settings)
this.settingApiOk = true
},
干脆再加個 await 吧
看上面的代碼都在前面加了 await
也都沒有用, 那索性再在 Object.assign()
前面加一個試試吧。
尼瑪居然成功了, 完全想不到是這個原因。 難道 Object.assign
是一個異步方法嗎?傻傻分不清。
換個 … 試試
Object.assign()
和 ...
都是對象合並的方法。那換個 ...
試試呢?
// this.fpSettings = await Object.assign(this.fpSettings, lastSettings, setting.settings)
this.fpSettings = await {...this.fpSettings, ...lastSettings, ...setting.settings}
很遺憾, 使用 ...
方式加 await 也不能解決問題。那么看來它和 Object.assign()
還是有區別的。那么區別是什么呢?
疑問
通過上面的情況, 有幾個問題存在。
Object.assign()
是一個異步操作嗎?為什么加await
就好了?Object.assign()
和...
有什么不同?