私はJavaScriptにかなり慣れており、反応します。 idが指定されたサーバーからcustomer_nameを取得するコンポーネントからのコールバックがあります。フェッチは機能し、console.logはフルネームを正しく出力しますが、最後の.thenのcustomer_nameは設定されず、関数は空の文字列を返します。何故ですか?
// 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;
}
Promisesを正しく理解していないと思います。 returnステートメントは、Promiseが解決される前に呼び出されるため、空の文字列が返されます。
これに取り組むための1つの方法は、次のような約束全体を返すことです。
// 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);
});
}
または、このようなasync/awaitを使用して、ES7アプローチを使用できます
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);
}
ご覧のとおり、2番目のアプローチはよりクリーンで読みやすいです。
結果は、関数を呼び出すコードで同じになります
tj_customer_name(1).then(fullName => {
console.log(fullName);
});
または
async function something() {
const fullName = await tj_customer_name(1);
console.log(fullName);
}
フェッチは非同期で、promiseを返すため、その性質上(.then
を使用して)非同期的にのみ監視できます。
おそらく、関数で作成したプロミスチェーンを返し、チェーンの最後のcustomer_name
コールバックで.then
を返す必要があります。
// 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:潜在的なネットワークの問題を処理するために.catch
ハンドラーを追加することを忘れないでください(参照: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch #Checking_that_the_fetch_was_successful )