React Native AsyncStorage返回promise而不是value

sfr*_*ini 7 javascript react-native

我知道这是RN中一个非常常见的问题,我仍然试图理解从属性文件加载数据时返回promise的非常可能的优势,而不仅仅是返回值,这使得链接请求非常麻烦......但无论如何.这是我现在所拥有的,它是AsyncStorage RN实现的包装器:

multiGet = async (key) => {
    var value = null;
    try {
      value = await AsyncStorage.multiGet(key).then(
        (values) => {
          value = values;
          console.log('Then: ',values);
        });
    } catch (error) {
      console.log('Error: ',error);
    }
    console.log('Final: ',value);
    return value;
    }
Run Code Online (Sandbox Code Playgroud)

此时,值未定义.在我的主要代码中,我有这个:

var filter = this._getFilter();
console.log('returned filter:',filter);
Run Code Online (Sandbox Code Playgroud)

_getFilter函数是使用AsyncStorage包装器的函数,但是'返回的过滤器'在第一个函数之前记录,所以它不会在继续之前等待返回的值,所以我得到一个未定义的值.

起初,我认为只是通过使用async/await AsyncStorage wold返回一个值而不是一个promise但是在测试之后,我得到的值是:

value = await AsyncStorage.getItem('key') 
Run Code Online (Sandbox Code Playgroud)

仍然是一个承诺,所以我必须使用then()来读取值.

基本上我在日志中看到的顺序是:

_getFilter
returned value: undefined
Then: value: here I get the correct value from the keys but the code already passed and I don't have the correct value in the variable
Run Code Online (Sandbox Code Playgroud)

我不知道发生了什么或如何正确处理这个问题.这应该是非常简单和常见的用例.

我很乐意在不使用第三方模块的情况下解决这个问题.

谢谢

解决方案 编辑:在了解了async/await和callbacks的概念后,我终于有了一个有效的代码.我不喜欢它,因为它使代码很难阅读.我可能需要重构它以使用promises但是现在,它可以工作.以下是一些片段,以防有人发现同样的问题:

this._getFilter(body,this._filterSearchCallback,callback);
Run Code Online (Sandbox Code Playgroud)

注意:我正在通过链发送正文,因为我在传递函数时"完成"信息.第二个参数是实际进行获取查询的第一个回调,第三个回调是获取函数的返回.

_getFilter(body,callback,returnCallback){

      {...}

      this._sh.multiGet(keysBanks).then(
        (banks) => {
          filter.banks = banks;
          console.log(banks);
          this._sh.multiGet(keysCards).then(
            (cards) => {
              console.log(cards);
              filter.credit_cards = cards;
              callback(body,filter,returnCallback);
            });
        }
      );

    }
Run Code Online (Sandbox Code Playgroud)

这里基本上我链接了几个获取因为我需要来自商店的几个值.这是我不喜欢的部分._sh是我的StorageHelper,它是AsyncStorage的包装器,没什么特别的.

multiGet = async (key) => {
    const value = await AsyncStorage.multiGet(key);
    return value;
    }
Run Code Online (Sandbox Code Playgroud)

然后我的最后一个回调实际上使得获取并将JSON响应发送到主屏幕中的本机:

_filterSearchCallback(body,filter,callback){

      body.filter = filter;

      return fetch(apiUrl, {method: 'post', body: JSON.stringify(body)})
      .then((response) => response.json())
      .then((responseJson) => {
        callback(responseJson);
      })
      .catch((error) => {
        console.error(error);
        callback(responseJson);
      });
    }
Run Code Online (Sandbox Code Playgroud)

我会改进这个并使它更干净但是现在,它有效.希望它也能帮助别人.

Cod*_*ngh 13

曾几何时,我遇到了同样的问题所以我做了什么,我将在这里与大家分享.

基本上,你的执行正在前进而没有任何价值,即未定义你现在得到的是什么,所以有3-4种方法可以摆脱这个:

1)异步等待2)回调

1)我们将从大多数人使用的回调开始.

我们将使用您的代码来实现此目的:

    _getFilter(key,callback)
{
    multiGet = (key) => {
        var collect;
        try {
          var value = AsyncStorage.multiGet(key).then(
            (values) => {
           //   value = values;
              console.log('Then: ',values);
             callback(values)
            });
        } catch (error) {
          console.log('Error: ',error);
        }
        console.log('Final: ',value);

        }
}

    this._getFilter(key,function(filter){
      console.log('returned filter:',filter);
    });
Run Code Online (Sandbox Code Playgroud)

2)异步/ AWAIT

如果你单独使用await,那么你会得到一个错误,在函数内使用await你必须通过在函数名之前设置async关键字来声明async函数.

 async _getFilter(key)
{

multiGet = async (key) => {
    var value,collect;
    try {
      value = await AsyncStorage.multiGet(key).then(
        (values) => {
          collect= values;
          console.log('Then: ',values);
        });
    } catch (error) {
      console.log('Error: ',error);
    }
    console.log('Final: ',value);
    return collect;
    }

//calling the async function

this._getFilter(key).then((filter)=>{
if(filter!=null)
console.log('returned filter:',filter)
else
console.log('error')
})
Run Code Online (Sandbox Code Playgroud)

希望这会清除你的概念,并帮助你与其他反应本地的开发人员.我看到很多人都在努力解决这个问题,所以今天我有机会清除你的疑虑.

干杯:)

  • 嗯,你确实证实了我的怀疑。我真的真的希望不必为了获得属性文件值而处理所有这些,但是......我想这就是要走的路。我会试试这个并确认这是否有效。 (2认同)

dho*_*lik 7

事情是await把承诺变成一个值,你不需要使用.then(). 请尝试以下操作:

const keys = await AsyncStorage.getAllKeys()
const values = await AsyncStorage.multiGet(keys)

// at this point `values` will have data for all keys 
Run Code Online (Sandbox Code Playgroud)

  • 这也是我的理解,但是要使用 await,我需要使我的函数异步,这使得 await 毫无意义,因为现在我再次返回了一个承诺。为了处理 now 异步函数,我需要在 main 方法中使用 then() 来处理它。 (2认同)