【问题标题】:React-native prevent functions from executing asynchronously?React-native 防止函数异步执行?
【发布时间】:2016-09-10 23:41:17
【问题描述】:

在我的 react Native 应用程序中单击一个按钮时,我会调用两个函数:getSolutionListFromDatabase,它将组件的状态设置为包含此解决方案列表,然后是 updateDatabaseSolutionList,它将一个元素添加到此列表并推送它回到 Firebase。然而,虽然应用程序的状态在第一个函数中被正确更新,但在第二个函数中,状态被记录为未定义,并且我的该函数的日志语句在第一个函数中的某些语句之前被调用。函数是否出于某种原因异步运行,这是 React native 的特性吗?如果是这样,在设置状态之前如何防止第二个函数执行?谢谢。

onSubmitPressed: function() {
    if (this.checkSolution) {
        this.getSolutionListFromDatabase();
        this.updateDatabaseSolutionList();
        Alert.alert(
            'Correct!',
            "Woohoo!"
        );
    }
},

getSolutionListFromDatabase: function() {
    var thisItemRef = itemsListRef.child(this.state.itemID);
    thisItemRef.once('value', (snap) => {
        var solutionList = snap.val();
        this.setState({
            solutionList: solutionList
        });
        console.log('solution is set as' + this.state.solutionList);
    });
},

updateDatabaseSolutionList: function() {
    var newSolutionList = [];
    console.log('solutionList undefined here' + this.state.solutionList);

    if (this.state.solutionList) {
        newSolutionList = this.state.solutionList;
        newSolutionList.push(this.props.itemID);
    }

    //then push new list to Firebase
},

【问题讨论】:

    标签: ios reactjs firebase react-native firebase-realtime-database


    【解决方案1】:

    逻辑将始终与answer to your previous question 中的相同。如果事件之间存在依赖关系,则应将调用移至第一个回调中:

    onSubmitPressed: function() {
        if (this.checkSolution) {
            this.getSolutionListFromDatabase();
        }
    },
    
    getSolutionListFromDatabase: function() {
        var thisItemRef = itemsListRef.child(this.state.itemID);
        thisItemRef.once('value', (snap) => {
            var solutionList = snap.val();
            this.setState({
                solutionList: solutionList
            });
            console.log('solution is set as' + this.state.solutionList);
            this.updateDatabaseSolutionList();
        });
    },
    
    updateDatabaseSolutionList: function() {
        var newSolutionList = [];
        console.log('solutionList undefined here' + this.state.solutionList);
    
        if (this.state.solutionList) {
            newSolutionList = this.state.solutionList;
            newSolutionList.push(this.props.itemID);
        }
    
        Alert.alert(
            'Correct!',
            "Woohoo!"
        );
        //then push new list to Firebase
    },
    

    如果您将先决条件(即solutionList)传递给需要它的函数,而不是使用字段/属性,那么这种类型的流程会变得更容易遵循:

    onSubmitPressed: function() {
        if (this.checkSolution) {
            this.getSolutionListFromDatabase();
        }
    },
    
    getSolutionListFromDatabase: function() {
        var thisItemRef = itemsListRef.child(this.state.itemID);
        thisItemRef.once('value', (snap) => {
            var solutionList = snap.val();
            this.updateDatabaseSolutionList(solutionList);
        });
    },
    
    updateDatabaseSolutionList: function(solutionList) {
        solutionList.push(this.props.itemID);
    
        Alert.alert(
            'Correct!',
            "Woohoo!"
        );
        //then push new list to Firebase
    },
    

    但更好的是直接将新值 push() 发送到 Firebase,而不是先下载整个数组,然后将其发送回并添加一个新项目:

    onSubmitPressed: function() {
        if (this.checkSolution) {
            itemsListRef.child(this.state.itemID).push(...);
        }
    },
    

    【讨论】:

      【解决方案2】:

      setState 不保证是同步的,所以你不能依赖它之后立即更新的状态。

      https://facebook.github.io/react/docs/component-api.html

      setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。调用此方法后访问 this.state 可能会返回现有值。

      无法保证对setState 的调用会同步操作,并且可能会批处理调用以提高性能。

      API 确实提供了一个回调,用于说明状态何时实际更新:

      void setState(
        function|object nextState,
        [function callback]
      )
      

      或者,您可以将解决方案列表直接传递给下一个函数,然后同时将它们设置为状态,这似乎是更好的选择。

      【讨论】:

      • 感谢您的提示。当我尝试通过仅返回 snap.val() 将解决方案列表直接传递给下一个函数时,该函数返回为未定义,即使它在函数中记录了 snap.val 的正确值。有什么想法可以在这里发生吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 2022-01-25
      • 1970-01-01
      • 2010-11-11
      • 2019-04-04
      • 1970-01-01
      相关资源
      最近更新 更多