ReactNative踩坑日志——使用async/await語法解決網絡請求的異步導致的指令執行順序錯亂問題


    轉載請注明原文地址:    

    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("登錄失敗")
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM