2017-10-29 176 views
6

說明: 我正在做一個反應本機應用程序,在那裏我有我下面GitHub上的用戶列表,我想實現的功能停止關注並刷新名單。提取API返回舊數據在本地做出反應

我做了兩個異步傭工與github API交互,一個取消關注用戶(通過PUT),另一個取得下列列表(通過GET)。我還在下列組件列表中添加了一個Firebase偵聽器。以下每個步驟都會導航到由非關注按鈕組成的單個配置文件視圖。當我點擊一個按鈕時,它應該取消關注用戶,更新組件中的以下列表,然後返回到以下組件列表。

問題 取消關注用戶正在按預期工作,但以下視圖列表仍包含舊列表。我的代碼正在返回舊數據,即使github API正在返回新的更新數據,所以我懷疑問題必須是我使用async/await的方式。

我甚至做了一個刷新按鈕來刷新以下列表,但新數據有時只返回,如1/20次。

UPDATE:測試多個方案後,我不認爲firebase是問題,因爲fetch正在返回相同的舊數據。我認爲主要問題可能在於撥打fetch。我也測試過從Postman獲取數據,並抓取正確的數據。

看起來好像fetch不按預期工作,因爲response.json()包含舊數據。我在這裏做了一個簡單的jsfiddle(你需要提供你自己的訪問令牌),它顯示get_following -> unfollow -> get_following工作成功,也就是說以下數據被修改。然而,在我的應用程序中,fetchunfollow之前返回相同的舊數據,即使github網站UI顯示更改並且Postman返回新的已修改數據。 我也更新了一些代碼。

代碼

以下列表

/** 
    * Listens for any changes on the database and updates the 
    * dataSource accordingly. 
    * @param {Firebase Object} ref 
    */ 
    _listenForData(ref) { 
     ref.on('value', (snapshot) => { 
      this.setState({ 
       dataSource: snapshot.val() 
      }, 
      this.setState({ 
       isLoading: false, 
      })); 
     }); 
    } 

    componentDidMount() { 
     // Sets up the listener for realtime changes. 
     GithubApi.get_followings(this.ref) 
     .then(_ => this._listenForData(this.ref)); 
    } 

個人用戶與取消關注按鈕

async unfollow() { 

    try { 
     let success = await GithubApi.unfollow_user(this.state.login); 
     console.log('unfollowed user'); 
     console.log(success); 
     if (success) { 
      // Updates database after unfollowing 
      console.log('update followings') 
      await GithubApi.get_followings(this.ref); 
      return true; 
     } 
    } catch (error) { 
     console.error(error); 
     return false; 
    } 
} 

render() { 
    const { goBack } = this.props.navigation; 
    return (
     <Button 
      title='Unfollow' 
      onPress={ 
       () => this.unfollow().then(_ => goBack()) 
      } 
     /> 
    ) 
} 

Github的阿比助手

const GithubApi = { 
    url: 'https://api.github.com/', 
    access_token: ..., 

    /** 
    * An asychronous helper function to grab data from github 
    * given an url and add data the firebase. 
    * 
    * @param {string} url 
    * @param {Firebase Object} firebaseRef 
    */ 
    _get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      if (responseStatus === 200) { 
       firebaseRef.set(responseJson, 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return false; 
     } catch (error) { 
      return false; 
     } 
    }, 

    /** 
    * Gets the user's following data and adds it to the database. 
    * @param {Firebase Object} firebaseRef 
    */ 
    get_followings: async function(firebaseRef) { 
     return await this._get_data_from_github_with_firebase(
      this.url + 'user/following?' + this.access_token, 
      firebaseRef 
     ); 
    }, 

    unfollow_user: async function(username) { 
     try { 
      let url = this.url + 'user/following/' + username + '?' + this.access_token; 
      let response = await fetch(url, { method: 'DELETE'}); 
      let responseStatus = await response.status; 
      if (responseStatus === 204) { 
       return true; 
      } 
      return false; 
     } catch (error) { 
      return false; 
     } 
    }, 
+0

'GithubApi.unfollow_user()'看起來像什麼? /什麼是'this.state.login'? –

+0

@ArmanCharan,對不起,我剛更新了代碼片段以包含'unfollower_user'。 'this.state.login'就是用戶的github登錄用戶名。 – ygongdev

+0

所有好兄弟。你是否想將你的'GithubApi'對象定義爲[Class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)?我從來沒有見過任何人在這樣的對象上調用過'this'。 –

回答

2

您在_get_data_from_github_with_firebase裏面缺失await。 嘗試改變函數將此:

_get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      var result = false 
      if (responseStatus === 200) { 
       result = await firebaseRef.set(responseJson, 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return result; 
     } catch (error) { 
      return false; 
     } 
    }, 

注意我強烈建議你使用redux-saga的同步動作。

+0

感謝您的輸入,但這也不起作用。結果也返回undefined。 – ygongdev

2

您是否有機會成爲前C開發人員?或者你被用來通過引用傳遞變量?

我覺得你的問題是,這一功能裏面你想通過引用返回一個值:

_get_data_from_github_with_firebase: async function(url, firebaseRef) { 
     try { 
      let response = await fetch(url); 
      let responseStatus = await response.status; 
      let responseJson = await response.json(); 
      var result = false 
      if (responseStatus === 200) { 
       result = await firebaseRef.set(responseJson, //You are executing a method by reference 
       (error) => { 
        if (error) { 
         console.log(error); 
         return false; 
        } else { 
         return true; 
        } 
       }); 
      } 
      return result; 
     } catch (error) { 
      return false; 
     } 
    }, 

也許更專業JS開發人員可以確認這是否會工作,但我不習慣這樣做。我會改變簽名,只是返回responseJson而不是像這樣設置它。

大概responseJson在這個函數裏面有一個值,但是在外面沒有定義。