Javascript JSON.stringify返回[]

时间:2018-06-09 04:50:25

标签: javascript json reactjs

我正在使用ReactJS,需要创建一个数组来插入数据,将其存储在localStorage中,以后再查看。我首先使用this.subscriptionsList = [];创建数组然后使用此方法检索数据。

  fetchNow = async (token, nextToken) => {
      fetch("somewebsite")
        .then(( unformattedData ) => {
          return unformattedData.json();
        })
        .then(( webData) => {
          for(let i = 0; i < webData.length; i++){
            this.subscriptionsList.push("someData");
          }
          if(webData.hasOwnProperty('token')){
            this.fetchNow(token, webData.token);
          }else{
            return;
          }
        })
      }

该功能尚未完成,因为它不是我问题的焦点。它工作正常并推送正确的数据。

我使用这种方法检索数据:

this.fetchNow(response.accessToken, "")
      .then( () => {
        console.log(this.subscriptionsList);
        console.log(JSON.stringify(this.subscriptionsList));
        localStorage.setItem("subscriptionsList", JSON.stringify(this.subscriptionsList));
        //console.log(JSON.parse(localStorage.getItem("subscriptionsList")));
      })

当我尝试使用JSON.stringify时出现问题。执行console.log(this.subscriptionsList)打印一个数组对象,其中包含所有数据。但是,当我去console.log(JSON.stringify(this.subscriptionsList))时,它会返回[]。此外,在打印对象本身时,属性length: 125但在执行console.log(this.subscriptionsList.length)时它返回0,当使用this.subscriptionsList[0]进行访问时,它返回undefined。我正在阅读规范,似乎JSON.stringify应该与javascript数组一起使用。我是否遗漏了特定的反应或者JSON.parse没有这个?

https://gyazo.com/72aafe248ef61649a38c06d03fb3d830
https://gyazo.com/c2690b4392774fe4a98254a4d15f3a32
https://gyazo.com/e0793b5ec05da4259e16100f275da414

2 个答案:

答案 0 :(得分:1)

您需要在fetchNow返回承诺链,否则您在尝试时无法链接到该承诺链。如果您希望将其链接在return,您还必须fetchNow调用fetchNow内的fetchNow = (token, nextToken) => { return fetch("somewebsite") .then(( unformattedData ) => { return unformattedData.json(); }) .then(( webData) => { for(let i = 0; i < webData.length; i++){ this.subscriptionsList.push("someData"); } if(webData.hasOwnProperty('token')){ return this.fetchNow(token, webData.token); } }) }

async

await函数不会神奇地使异步操作同步。他们(1)返回Promises,(2)允许await关键字。但由于您没有使用fetchNow,因此async不需要fetch,并且由于Promise链已经是async,您可以在没有async的情况下直接返回。

如果您 想要使用awaitfetchNow = async (token, nextToken) => { const response = await fetch("somewebsite"); const webData = await response.json(); for(let i = 0; i < webData.length; i++){ this.subscriptionsList.push("someData"); } if(webData.hasOwnProperty('token')){ await this.fetchNow(token, webData.token); } // async function will automatically return a Promise that resolves when the end is reached } ,那么这会让代码更平坦,更容易理解:

i

答案 1 :(得分:1)

这就是发生的事情.... console.log(JSON.stringify(something))做的是它序列化立即值并打印序列化引用。(换句话说,它创建克隆副本并打印克隆副本而不是原始参考它不会等待提升/变异的值)。 console.log(something)所做的是它引用原始值并打印实际结果(变异/悬挂)而不是直接结果。由于您的方法是异步方法,您可以清楚地观察到这一点。您可以等到asyc调用完成,然后您可以将实际变量推送到localStorage。 (请注意,即使本地存储也存储为序列化值)

编辑1: -

let onComplete = (subscriptionsList) => {
    console.log(JSON.stringify(subscriptionsList));
    localStorage.setItem("subscriptionsList", JSON.stringify(subscriptionsList));
    //console.log(JSON.parse(localStorage.getItem("subscriptionsList")));
}

fetchNow = async (token, nextToken, onComplete) => {
  fetch("somewebsite")
    .then(( unformattedData ) => {
      return unformattedData.json();
    })
    .then(( webData) => {
      for(let i = 0; i < webData.length; i++){
        this.subscriptionsList.push("someData");
      }
      if(webData.hasOwnProperty('token')){
        this.fetchNow(token, webData.token);
      }else{
        onComplete(this.subscriptionsList);
        return;
      }
    })
}

this.fetchNow(response.accessToken, "", onComplete)
  .then( () => {
    console.log("direct call ", this.subscriptionsList);
})