Fetch: set variable with fetch response and return from function [duplicate]

孤街浪徒 提交于 2019-11-29 01:01:19

问题


This question already has an answer here:

  • How do I return the response from an asynchronous call? 36 answers

I'm quite new with JavaScript and react. I have a callback from a component that gets a customer_name from a server given a id. The fetch works and the console.log prints the fullname correctly, but the customer_name in the last .then is not set, and the functions returns an empty string. Why is that?

// Gets the fullname of the customer from an id.
tj_customer_name(id) {
  let customer_name = '';

 fetch(`/customers/${id}.json`, {
   headers: API_HEADERS,
   credentials: 'same-origin'
 })
 .then((response) => {
   if(response.ok) {
     return response.json();
   } else {
     throw new Error('Server response wasn\'t OK');
   }
 })
 .then((json) => {
   customer_name = json.first_name.concat(' ').concat(json.last_name);
   console.log(customer_name);
 });
 return customer_name;
}

回答1:


I think you don't understand Promises correctly. The return statement will be called before the Promise is resolved, thus returning empty string.

One way to tackle this, is to return the whole promise like this:

// Gets the fullname of the customer from an id.
tj_customer_name(id) {
  let customer_name = '';

  return fetch(`/customers/${id}.json`, {
    headers: API_HEADERS,
    credentials: 'same-origin'
  })
  .then((response) => {
    if(response.ok) {
        return response.json();
    } else {
        throw new Error('Server response wasn\'t OK');
    }
  })
  .then((json) => {
    return json.first_name.concat(' ').concat(json.last_name);
  });
}

or you can use the ES7 approach, using async/await like this

async function tj_customer_name(id) {
    const response = await fetch('some-url', {});
    const json = await response.json();

    return json.first_name.concat(' ').concat(json.last_name);
}

As you can see, the second approach is much cleaner and readable.

The result will be the same in the code which calls your function

tj_customer_name(1).then(fullName => {
    console.log(fullName);
});

or

async function something() {
    const fullName = await tj_customer_name(1);
    console.log(fullName);
}



回答2:


Because fetch is asynchronous and returns a promise, which by its nature can only be observed asynchronously (using .then).

You should probably just return the promise chain you create in your function and return customer_name in the last .then callback of the chain:

// Gets the fullname of the customer from an id.
tj_customer_name(id) {

 // return the entire promise chain
 return fetch(`/customers/${id}.json`, {
   headers: API_HEADERS,
   credentials: 'same-origin'
 })
 .then((response) => {
   if(response.ok) {
     return response.json();
   } else {
     throw new Error('Server response wasn\'t OK');
   }
 })
 .then((json) => {
   const customer_name = json.first_name.concat(' ').concat(json.last_name);
   return customer_name; // return the customer_name here
 });
}

// later, use the function somewhere
this.tj_customer_name(21).then((customer_name) => {
    // do something with the customer_name
});

PS: Don't forget to add a .catch handler to handle potential network issues (see: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful)



来源:https://stackoverflow.com/questions/38869197/fetch-set-variable-with-fetch-response-and-return-from-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!