Skip to content

有时获取不到刚存的数据 #270

@yesgit

Description

@yesgit

场景是登录成功后保存token,然后用token去获取用户其他数据,但是后续拿到的token总是空的,多次重新登录都不行,除非重新安装应用。

测试环境从来没遇到,生产上Android、iPhone、iPad都遇到过,看代码没看出问题,很难复现。

依赖:

    "react-native": "0.72.3",
    "react-native-storage": "^1.0.1",
    "@react-native-async-storage/async-storage": "^1.19.2",

代码:

//import
import AsyncStorage from '@react-native-async-storage/async-storage';
import Storage from 'react-native-storage';

//storage声明和配置
var storage = new Storage({
  size: 1000,
  storageBackend: AsyncStorage,
  defaultExpires: null,
  enableCache: true,
  sync: {}
})
global.storage = storage;
//写入
export function setStorage(keyId,data,i){
  if(i == undefined){
    i = null
  }
  let key = keyId;
  let id = undefined;
  if(keyId.indexOf('-') != -1){
    let parts = keyId.split('-');
    key = parts[0];
    id = parts[1];
  }
  storage.save({
      key: key, 
      data: data,
      expires: i,
      id: id
    });
}
//读取
export function getStorage(keyId,callback){
  let key = keyId;
  let id = undefined;
  if(keyId.indexOf('-') != -1){
    let parts = keyId.split('-');
    key = parts[0];
    id = parts[1];
  }
  if(!callback)
  return new Promise((resolev, reject)=>{
    storage.load({
    key: key,
    id: id,
    autoSync: true,
    syncInBackground: true,
    syncParams: {
      extraFetchOptions: {
      },
      someFlag: true,
    },
    }).then(ret => {
      resolev(ret);
    }).catch(async err => {
    switch (err.name) {
        case 'NotFoundError':
          reject(new Error('Not found ' + key));
          // TODO;
          break;
        case 'ExpiredError':
           //这里有一段重新获取和写入Token的逻辑
            break;
          }
          reject(new Error(key + ' is expired'));
            break;
        default:
            reject(new Error('Not found ' + key));
    }
  })
  });
  storage.load({
    key: key,
    id: id,
    autoSync: true,
    syncInBackground: true,
    syncParams: {
      extraFetchOptions: {
      },
      someFlag: true,
    },
    }).then(ret => {
      callback(ret)
    }).catch(async err => {
    switch (err.name) {
        case 'NotFoundError':
          callback(null)
          break;
        case 'ExpiredError':
          //这里有一段重新获取和写入Token的逻辑
            break;
        default:
            callback(null);
    }
  })
}

//异步读取函数
export const getTempInfo = async (key) => {
  let result = '';
  try {
    result = await getStorage(key);
  } catch ( err ) {
    console.log(err.message);
    return '';
  }
  return result;
}

//登录成功的代码节选
if (succ && succ.code === '0000') {
    storage.remove({key:'token'});//移除旧token
    setStorage('token', succ.content.token, tokenTime); //写入新token,并设置过期时间
    getTempInfo("token").then((token) => { //这里获取token,但是获取为空
    succallback();
} else {
    errcallback(succ.message);
}

现在怀疑的地方:

  1. 达到了Android 6mb上限。但是ios也有这个问题,所以,至少不完全是这个原因。针对性测试也未复现。
  2. 达到了1000条限制。按理说达到限制后,循环使用,会把最旧的踢掉,不应该出现这个问题。针对性测试也未复现。
  3. enableCache:true 启用内存缓存导致的。会不会是缓存刷新问题?这个暂时没有排除。但接连多个请求都没有拿到token。
  4. autoSync: true, 导致的,没有同步,却启用了同步。这个不知道会不会有问题。测试环境似乎从来没出现问题。
  5. save后立即load导致的。因为save是异步的,所以可能load不到。这个也不太像,接连多个请求都拿不到,后续请求也拿不到。

有谁遇到或知道这个问题怎么解决吗?或有什么主意吗?辛苦帮忙回复,不胜感谢!!!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions