2016-08-10 4 views
1

zurückkommen Ich bin ziemlich neu mit JavaScript und reagiere. Ich habe einen Rückruf von einer Komponente, die einen customer_name von einem Server mit einer ID erhält. Der Abruf funktioniert und die console.log druckt den vollständigen Namen korrekt, aber der Kunde_name in der letzten .Then ist nicht festgelegt, und die Funktionen gibt eine leere Zeichenfolge zurück. Warum das?Fetch: Variable mit Fetch-Antwort setzen und von Funktion

// 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

Ihr Problem erfordert, dass der letzte 'customer_name' ist * nicht * innerhalb der' then' als du hast behauptet – Bergi

Antwort

3

Weil fetch asynchron ist, und gibt ein Versprechen, die von Natur aus nur asynchron beobachtet werden (unter Verwendung von .then).

Sie sollten wahrscheinlich zurückkehren nur das Versprechen Ketten Sie in Ihrer Funktion erstellen und zurück customer_name im letzten .then Rückruf der Kette:

// 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: Vergessen Sie nicht, einen .catch Handler zu behandeln Potenzial hinzufügen Netzwerkprobleme (siehe: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful)

9

Ich denke, Sie verstehen Versprechen nicht richtig. Die return-Anweisung wird aufgerufen, bevor die Promise aufgelöst wird, wodurch eine leere Zeichenfolge zurückgegeben wird.

Eine Möglichkeit, dies zu bewältigen, ist das ganze Versprechen wie diese zurück:

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

oder können Sie das ES7 Ansatz verwenden, mit Asynchron/erwarten ähnliche

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

Wie Sie können Sehen Sie, der zweite Ansatz ist viel sauberer und lesbarer.

Das Ergebnis wird das gleiche in dem Code sein, der Ihre Funktion ist

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

oder

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