Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 异步存储行为_Javascript_Reactjs_Asynchronous_React Native_Expo - Fatal编程技术网

Javascript 异步存储行为

Javascript 异步存储行为,javascript,reactjs,asynchronous,react-native,expo,Javascript,Reactjs,Asynchronous,React Native,Expo,我遇到了一个奇怪的AsyncStorage行为,我无法理解,如果有人能向我解释幕后发生了什么(即失败案例和原因),我将不胜感激 以下是我正在编写的代码: componentDidMount() { let _this = this; AsyncStorage.getItem('token', (err, data) => { setTimeout(() => { if(data !== null

我遇到了一个奇怪的
AsyncStorage
行为,我无法理解,如果有人能向我解释幕后发生了什么(即失败案例和原因),我将不胜感激

以下是我正在编写的代码:

componentDidMount() {
        let _this = this;

        AsyncStorage.getItem('token', (err, data) => {
            setTimeout(() => {
                if(data !== null){
                    this.setState({isReady: true, isLoggedIn: true});
                    store.dispatch({type: t.LOGGED_IN, token: data});
                }
                else{
                    this.setState({isReady: true, isLoggedIn: false})
                    store.dispatch({type: t.LOGGED_OUT});
                }
            }, 3000)
            console.log(err);
        });
    }
如您所见,我正在根据文档向
getItem()
传递一个
callback
函数,它基本上告诉我用户之前是否登录过,之后是否没有注销(即令牌仍然存在于设备/应用程序的某处)。 这段代码第一次成功,检索了我通过reducer存储的旧令牌:

export default function authReducer(state = initialState, action)
{
    switch (action.type) {
        case t.LOGGED_IN:{
            AsyncStorage.setItem('token', action.token);
            return Object.assign({}, state, { isLoggedIn: true, token: action.token });
        }
        case t.LOGGED_OUT:{
            AsyncStorage.removeItem('token');
            return Object.assign({}, state, {isLoggedIn: false, token: null});
        }
        default:
            return state;
    }
}
但是,在我第二次重新加载应用程序时,
AsyncStorage
将始终无法检索数据,即使在我多次尝试登录之后也是如此

我也尝试了不同的
异步存储
调用,即使用
等待
。然后
加上
。捕获
,但它们都会导致相同的结果

我的问题是:

  • 在失败案例中,我的印象是,
    getItem()
    仍将调用我传递的回调函数,因为参数列表上有一个
    错误。但是,在上述情况下,我的console.log从未运行过。我是不是在期待一些我不该在这里的事情

  • 为什么它只会从第二次失败开始?是否存在这样的情况:在同一个键上多次调用
    setItem()
    ,而不删除它会导致存储失败?(我确信第一次尝试是成功的,因为我打印了从异步存储中检索到的令牌)

  • 这与我从Expo加载我的应用程序并用CRNA初始化应用程序这一事实有关吗?这会使异步存储持久性质量有所不同吗

  • 提前感谢!:)


    编辑:进一步检查后,停止打包程序并再次运行似乎允许应用程序再次成功检索旧令牌,但如果我在编辑代码后再次刷新应用程序,
    getItem()
    将再次失败。这是Expo和持久存储的问题吗?

    多亏了我的一位更有经验的程序员朋友,现在这个问题已经解决了。 原来我的错误是我把
    AsyncStorage.setItem()
    调用放在了reducer中,他说reducer本质上是
    确定性的。
    在分派之前,我将调用移到了该类的
    actions.js
    ,它就可以工作了

    所以不是

    export default function authReducer(state = initialState, action)
    {
        switch (action.type) {
            case t.LOGGED_IN:{
                AsyncStorage.setItem('token', action.token);
                return Object.assign({}, state, { isLoggedIn: true, token: action.token });
            }
            case t.LOGGED_OUT:{
                AsyncStorage.removeItem('token');
                return Object.assign({}, state, {isLoggedIn: false, token: null});
            }
            default:
                return state;
        }
    }
    
    是的

    export default function authReducer(state = initialState, action)
    {
        switch (action.type) {
            case t.LOGGED_IN:{
                return Object.assign({}, state, { isLoggedIn: true, token: action.token });
            }
            case t.LOGGED_OUT:{
                return Object.assign({}, state, {isLoggedIn: false, token: null});
            }
            default:
                return state;
        }
    }
    
    再加上这个

    export function login(data, successCB, errorCB) {
        return (dispatch) => {
            api.login(data, function (success, data, error) {
                if (success && data.exists) {
                    AsyncStorage.setItem('token', data.token); //NOTE THIS
                    dispatch({type: t.LOGGED_IN, token: data.token});
                    successCB(data);
                }else if (error) errorCB(error)
            });
        };
    }
    
    export function signOut(successCB, errorCB){
      return (dispatch) => {
        AsyncStorage.removeItem('token'); //NOTE THIS
        dispatch({type: t.LOGGED_OUT});
        successCB();
      }
    }
    
    但是我的问题仍然存在(请原谅我的双关语),“为什么简单的修改有效?我理解了
    减缩器和
    调度器的机制吗?”

    另外,确定性的
    意味着什么,与
    异步调用的不兼容性有什么关系


    如果有人能向我解释这个概念,那就太棒了D

    还原剂必须无副作用,因为它是一种纯功能

    如报告中所述

    它们必须是纯函数——对于给定输入返回完全相同的输出的函数。它们也应该没有副作用

    副作用-当程序从其范围外更改变量时


    一个更好的方法是使用,这就像一个单独的线程为您的副作用模型。

    啊,我明白了,一定错过了那个!谢谢你(堆!)