轉載請注明原文地址:
ReactNative的fetch是天然的異步請求,因此,如果你在一個代碼塊中使用了fetch,那么在執行的時候程序不會等待網絡響應結束才執行下一條代碼,而是會直接按順序執行完整個代碼塊。而這樣的話,某些具有先后條件的代碼就會存在結果混亂等問題。
比如:一個登錄方法
doLogin(){ //1:根據輸入的工號、密碼進行登錄 fetch(this.hostIP + "/login?user="+this.user+"&password="+this.password).then((response) => response.json()) .then((json) => { //處理響應 this.isLogin = true }).catch((error) => { alert("登錄失敗,請檢查網絡連接!") }) //2:根據登錄結果控制跳轉 if(isLogin){ this.props.navigation.navigate('Menu') }else{ alert("登錄失敗") } }
理論上,我們的執行邏輯是先用fetch進行登錄,然后根據后台返回結果,控制跳轉或彈出失敗提示。
然而上述代碼在執行時就會出現一旦點擊登錄按鈕就會立刻彈出“登錄失敗”的提示,等再次點擊登錄按鈕,卻又跳轉到了主頁面。
原因就是因為,第一次點擊登錄按鈕時,fetch異步執行,結果還沒有返回,而RN已經執行到下面的if-else代碼塊了,因此登錄失敗。
而再次點擊時,上一次的fetch結果已經返回了,所以if-else語句就會根據上一次點擊時的fetch結果作為判斷條件來執行了。
那么,怎么解決呢?ES7提供了終極異步解決方案——async/await語法
我們可以在定義一個含有異步操作的方法時,在其前面加上 async 關鍵字,標示該方法是異步方法;
而在方法中,使用 await 關鍵字修飾異步操作,該關鍵字的作用時:等待該語句執行完畢才執行下一條代碼。
這樣,我們在具有先后條件限制的代碼塊中,用await關鍵字修飾其中的異步代碼,即可保證按照順序執行,從而得到正確的結果了。
改進后的登錄方法:
async doLogin(){ //1:根據輸入的工號、密碼進行登錄 await fetch(this.hostIP + "/login?user="+this.user+"&password="+this.password).then((response) => response.json()) .then((json) => { //處理響應 this.isLogin = true }).catch((error) => { alert("登錄失敗,請檢查網絡連接!") }) //2:根據登錄結果控制跳轉 if(isLogin){ this.props.navigation.navigate('Menu') }else{ alert("登錄失敗") } }