动态

详情 返回 返回

當從localStorage中獲取數據時,如何做異常處理? - 动态 详情

提出問題

下面的代碼在有初始值的情況下,能夠工作的很好,但是當localStorage中存在非法的數據時就會拋出異常,如果你的程序沒有做好異常處理,就會崩潰。

const todosStr = localStorage.getItem('todos')
const todos = JSON.parse(todosStr)

分析問題

能夠拋出異常的位置在JSON.parse,當JSON.parse解析的內容為以下情況時,就會拋出異常:

1 傳參是無效的json字符串

JSON.parse("{name: 'John'}");
// Uncaught SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
JSON.parse('')
// Uncaught SyntaxError: Unexpected end of JSON input

2 解析的內容是undefined

JSON.parse(undefined)
// Uncaught SyntaxError: Unexpected end of JSON input

解決問題

知道了JSON.parse可能會拋出異常,我們在使用localStorage時做一下異常處理:

function getFromLocalStorage(key) {
  try {
    return JSON.parse(localStorage.getItem(key));
  } catch (error) {
    console.error(`Error parsing data from localStorage key "${key}": ${error}`);
    return null;
  }
}

我們在異常發生的時候,返回了nullgetItem在獲取不到數據時也是返回null,這樣用户就可以平滑的做空處理。

const todos = getFromLocalStorage('todos') || [];

總結問題

1 只做最關鍵的工作
我們沒有在localStorage.getItem('todos')處做額外的異常處理和空判斷,因為問題的源頭髮生在JSON.parse處。

2 保持接口的一致性
我們在異常處理時,與getItem保持了一致的返回值,這樣在調用處就不用擔心意料之外的情況發生。

3 只封裝不可變的部分
我們沒有將空判斷放到函數裏面,因為這是可變的部分,目標數據可能是字符串,也可能是數組,如果封裝到內部就不夠靈活了。相反,在外面做空判斷就非常靈活。

注意

如果是在ts中,還需要對localStorage.getItem(key)做一下null的判斷,因為ts判斷JSON.parse只能接受字符串。

function getFromLocalStorage(key: string) {
  const data = localStorage.getItem(key)

  if (data === null) {
    return null;
  }

  try {
    return JSON.parse(data);
  } catch (error) {
    console.error(`Error parsing data from localStorage key "${key}": ${error}`);
    return null;
  }
}
user avatar nihaojob 头像 zourongle 头像 zero_dev 头像 libubai 头像 tanggoahead 头像 yangxiansheng_5a1b9b93a3a44 头像 hightopo 头像 justbecoder 头像 ruanjiankaifa_xiaofanya 头像 evilboy 头像 maomaoxiaobo 头像 jamesfancy 头像
点赞 28 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.