首页 > 解决方案 > AsyncStorage 在 mergeItem 期间抱怨数组和对象不兼容

问题描述

我试图弄清楚为什么AsyncStorage在 React Native 应用程序中拒绝mergeItem处理我的数据。我的功能如下所示:

const arrToObj = (array) =>
  array.reduce((obj, item) => {
    obj[Object.keys(item)[0]] = Object.values(item)[0]
    return obj
  }, {})

export const addThingToThing = async (title, thing) => {
  try {
    let subThings = []
    let things = {}
    await AsyncStorage.getItem(THINGS_STORAGE_KEY)
      .then((things) => {
        let subThings = []
        Object.values(JSON.parse(decks))
          .map((thing) => {
            if (Object.keys(thing)[0] === title) {
              subThings = [...Object.values(thing)[0].subThings, subThing]
            }
          })
        return { decks, subThings }
      })
      .then(({ decks, subThings }) => {
        const obj = {
          ...arrToObj(JSON.parse(things)),
          [title]: {
            subThings
          }
        }
        console.log(JSON.stringify(obj))
        AsyncStorage.mergeItem(THINGS_STORAGE_KEY,
          JSON.stringify(obj))
      })
  } catch (error) {
    console.log(`Error adding thing to thing: ${error.message}`)
  }
}

当我执行执行此操作时,我得到:

13:35:52: {"test":{"subThings":[{"one":"a","two":"a"}]},"test2":{"title":"test2","questions":[]}}
13:35:55: [Unhandled promise rejection: Error: Value [{"test":{"title":"test","subThings":[]}},{"test2":{"title":"test2","subThings":[]}}] of type org.json.JSONArray cannot be converted to JSONObject]

这令人困惑,因为当数据被打印出来时,它是一个带有 的对象{...},但AsyncStorage显示的是一个带有 的数组[...]。有什么我想念的吗?这对我来说似乎很愚蠢,我似乎无法弄清楚如何让 RN 发挥得很好。

PS。IMO 数据的结构很糟糕,但这是我正在使用的。我没有决定,也无法改变。

标签: reactjsreact-nativeasyncstorage

解决方案


我记得使用,它与返回 PromisesAsyncStorage有根本的不同。localStorage

您的代码看起来很好,这使得这超级混乱,但我突然怀疑问题可能是由于缺少await关键字。

尝试:

.then(async ({ decks, subThings }) => {
  const obj = {
    ...arrToObj(JSON.parse(things)),
    [title]: {
      subThings
    }
  }
  console.log(JSON.stringify(obj))
  // We are adding await here
  await AsyncStorage.mergeItem(THINGS_STORAGE_KEY, JSON.stringify(obj))
})

在继续之前,这可能是一个经典的“不等待 Promise 解决”,异步问题。如果是这样,请不要删除此问题。将来可能对包括我自己在内的其他人都有帮助。

这是我认为正在发生的事情:

  1. JavaScriptAsyncStorage.mergeItem()扔进函数队列

  2. 这个函数没有await返回 Promise

  3. 解释器不等待它解析并立即移动到下一行代码

  4. 没有下一行代码,因此它会在then()0.1 毫秒后从块中返回(请记住,它隐含地在return undefined异步函数内部执行与 相同的操作resolve(undefined),关键是它正在尝试解析整个链备份到await AsyncStorage.getItem(THINGS_STORAGE_KEY)

  5. obj之后 0.1 毫秒收集垃圾

  6. AsyncStorage.mergeItem()在预期的地方观察到一个虚假的值obj,但我实际上并不确定。它可能没有执行第 5 步或第 6 步,而是mergeItem在尝试解析getItem链时检测到仍处于未决状态,无论哪种方式:

  7. AsyncStorage 然后给出一个令人困惑的错误消息


推荐阅读