【问题标题】:How to store a Promise's resolve into a variable using Fetch (not ajax)如何使用 Fetch(不是 ajax)将 Promise 的解析存储到变量中
【发布时间】:2019-02-06 18:00:30
【问题描述】:

以下代码运行良好,并将从网站获取的信息记录到控制台(输出已经为 json 格式的简单文件):

getData = url => {
  fetch(url)
    .then(response => {
      if (response.status !== 200) {
        console.log(
          "Looks like there was a problem. Status Code: " + response.status
        );
        return; //returns undefined!
      }

      // Examine the text in the response
      response.json().then(data => {
        console.log(data);
      });
    })
    .catch(function(err) {
      console.log("Fetch Error :-S", err);
    });
};

getData(urlToFetch); // logs to console the website call: a json file

我想将该 fetch 的内容值存储在一个变量中以供以后使用。

所以,当我改变时:

console.log(data);

到:

return data;

我得到一个未定义的。有什么帮助吗?

【问题讨论】:

  • 你试过getData(urlToFetch).then(x => console.log(x));吗?并在response之前添加return
  • 看起来您正在尝试同步获取异步结果
  • 我认为你是对的@JaromandaX return resolve(data) 会修复它吗?
  • 以何种方式修复什么?您的代码中没有名为 resolve 的函数

标签: javascript promise response fetch


【解决方案1】:

因为您在 getData 函数中使用 .catch,如果出现其他问题,您的函数也将解析 undefined。如果你想记录它,那么你需要将错误作为拒绝承诺返回,以便调用者可以处理错误,并且在承诺解决时不会获得未定义的数据值。

您可以return Promise.reject("no 200 status code") 拒绝,return response.json() 解决如果您想添加.then(x=>console.log(x)),您仍然需要返回一些东西,否则调用 getData 的东西将解析为 undefined:

getData = url => {
  fetch(url)
    .then(response => {
      if (response.status !== 200) {
        console.log(
          "Looks like there was a problem. Status Code: " + response.status
        );
        return Promise.reject(//reject by returning a rejecting promise
          "Looks like there was a problem. Status Code: " + response.status
        );
      }

      // Examine the text in the response
      response.json().then(data => {
        console.log(data);
        return data;//still need to return the data here
      });
    })
    .catch(function (err) {
      console.log("Fetch Error :-S", err);
      //return the reject again so the caller knows something went wrong
      return Promise.reject(err);
    });
};

getData(urlToFetch) // logs to console the website call: a json file
.then(
  x=>console.log("caller got data:",x)
)
.catch(
  e=>console.log("caller got error:",e)
);

【讨论】:

    【解决方案2】:

    您可以使用 ES6 async-await 轻松完成此操作:

    使用 async-await,您的代码将如下所示:

    function getData(url){
      return new Promise((resolve, reject) => {
       fetch(url)
        .then(response => {
          if (response.status !== 200) {
            console.log(
              "Looks like there was a problem. Status Code: " + response.status
            );
            return; //returns undefined!
          }
    
          // Examine the text in the response
          response.json().then(data => {
            resolve(data);
          });
        })
        .catch(function(err) {
          console.log("Fetch Error :-S", err);
          reject(err)
        });
     })
    }
    
    // Then call the function like so:
    
    async function useData(){
      const data = await getData(urlToFetch);
    
      // console.log(data) ===> result;
    }
    
    

    【讨论】:

    • 还是不兼容老IE
    【解决方案3】:
    return; //returns undefined!
    

    您没有返回任何内容,因此 return 本身会返回 undefined,除非您为其提供值。

    您需要存储承诺,当您需要一个值时,您必须解决它。我会改变这个:

     // Examine the text in the response
      response.json().then(data => {
        console.log(data);
      });
    

    到这里:

     // Examine the text in the response
      return response.json();
    

    然后调用 getData 并解决承诺:

    getData(urlToFetch).then(data => {
        // Code to use data
    })
    

    或者将promise存储在变量中,稍后使用:

    let result = getData(urlToFetch);
    
    result.then(data => {
        // so whatever with data
      });
    

    【讨论】:

    • 因为 getData 从 fetch 中捕获被拒绝的 Promise,并且不会在拒绝处理程序中返回任何内容,所以当 fetch 返回被拒绝的 Promise 时,getData 仍将解析为 undefined。
    【解决方案4】:

    这里发生的是,你在then 块下。您的 getData 函数在调用 fetch 后立即返回数据。它不会等待异步获取操作接收回调然后调用内部函数。

    所以 then 函数里面的 return 没有什么可返回的。这就是它不起作用的原因。

    相反,您可以从 getData 函数返回一个 Promise 并在其上调用 then 以获取数据。我前段时间遇到过类似的问题。

    一个例子:(未测试)

    getData = url => {
      new Promise(function (resolve, reject) {
       fetch(url)
        .then(response => {
          if (response.status !== 200) {
            console.log(
              "Looks like there was a problem. Status Code: " + response.status
            );
            reject(); //returns undefined!
          }
    
          // Examine the text in the response
          response.json().then(data => {
            resolve(data);
          });
        })
        .catch(function(err) {
          console.log("Fetch Error :-S", err);
        });
      };
    };
    getData(urlToFetch).then(data => /*do something*/ ); // logs to console the website call: a json file
    

    所以当数据可用时,你可以调用 resolve(data),它会根据你的 promise 调用 then 方法。

    希望对你有帮助。

    【讨论】:

    • 不需要new Promise 因为fetch(url) 返回一个承诺:fetch(url).then(res=>if()return Promise.reject(...) else return res.json()
    • 当 fetch 返回一个被拒绝的承诺时,getData 仍然会解析为 undefined。
    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2016-10-23
    • 2016-11-08
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    相关资源
    最近更新 更多