2017-10-29 175 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在这个函数里面有一个值,但是在外面没有定义。