admin管理员组

文章数量:1332873

The following code works well and logs to the console a fetch from a website (that outputs a simple file already in json format):

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

I want to store that fetch's content values in a variable for later use.

So, when I change:

console.log(data);

to:

return data;

I get an undefined. Any help?

The following code works well and logs to the console a fetch from a website (that outputs a simple file already in json format):

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

I want to store that fetch's content values in a variable for later use.

So, when I change:

console.log(data);

to:

return data;

I get an undefined. Any help?

Share Improve this question edited Dec 12, 2017 at 14:51 Mauricio Maroto asked Dec 12, 2017 at 5:17 Mauricio MarotoMauricio Maroto 1191 gold badge2 silver badges11 bronze badges 5
  • have you try getData(urlToFetch).then(x => console.log(x));? and add return before response – langitbiru Commented Dec 12, 2017 at 5:31
  • 1 looks like you're trying to get an asynchronous result synchronously – Jaromanda X Commented Dec 12, 2017 at 5:43
  • 4 Possible duplicate of How do I return the response from an asynchronous call? – ponury-kostek Commented Dec 12, 2017 at 8:34
  • I think you are right @JaromandaX Would return resolve(data) fix it? – Mauricio Maroto Commented Dec 12, 2017 at 14:52
  • Fix what in which way? There is no function called resolve in your code – Jaromanda X Commented Dec 12, 2017 at 20:25
Add a ment  | 

4 Answers 4

Reset to default 2

Because you .catch in your getData function if something else goes wrong your function will resolve undefined as well. If you want to log it then you need to return the error as a rejecting promise so the caller can handle the error and not get an undefined value for data when the promise resolves.

You can return Promise.reject("no 200 status code") for rejecting and return response.json() for resolve If you want to add .then(x=>console.log(x)) you still need to return something or the thing calling getData will resolve to 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)
);

You could use ES6 async-await to get this done easily:

Using async-await, your code will look like this:

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;
}

return; //returns undefined!

You aren't returning anything, so return by itself returns undefined unless you supply it with a value.

You need to store the promise and when you need a value, you will have to resolve it. I would change this:

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

to this:

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

Then call getData and either resolve the promise:

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

Or store the promise in the variable and use it later:

let result = getData(urlToFetch);

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

What happens here is, you are under then block. Your getData functions returns the data as soon as it call fetch. It doesn't wait for the async fetch opertion to receive callback and then call function inside then.

So the return inside then function have nothing to return to. That's why it doesn't work.

Instead you can return a promise from the getData function and call then on it to get the data. I faced a similar issue sometime ago.

An example: (not tested)

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

So when the data is available, you can call resolve(data) and it will invoke then method on your promise.

Hope it helps.

本文标签: javascriptHow to store a Promise39s resolve into a variable using Fetch (not ajax)Stack Overflow