2016-08-10 10 views
1

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

あなたの関数を呼び出すコードで同じになりますあなたが主張した – Bergi

答えて

3

ため、フェッチは非同期であり、その性質によってのみ(.thenを使用して)非同期的に観察することができる約束を返します。

あなたはおそらくあなたがあなたの関数で作成する約束チェーンを返し、チェーンの最後の.thenコールバックでcustomer_nameを返す必要があります:

// 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を参照)

9

私はあなたが正しく約束を理解していないと思います。 returnステートメントは、Promiseが解決される前に呼び出され、空の文字列を返します。

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

のように待って非同期を使用して、ES7のアプローチを使用することができます。これに対処する

一つの方法は、このような全体の約束を返すことです2番目のアプローチははるかにクリーンで読みやすいです。

結果はあなたの問題は、最後の `customer_name`として` then`内* *ではないということです

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

または

async function something() { 
    const fullName = await tj_customer_name(1); 
    console.log(fullName); 
} 
関連する問題