成功時と失敗時にJSONデータを返すHTTP APIがあります。
失敗の例は次のようになります。
~ ◆ http get http://localhost:5000/api/isbn/2266202022
HTTP/1.1 400 BAD REQUEST
Content-Length: 171
Content-Type: application/json
Server: TornadoServer/4.0
{
"message": "There was an issue with at least some of the supplied values.",
"payload": {
"isbn": "Could not find match for ISBN."
},
"type": "validation"
}
JavaScriptコードで達成したいのは、次のようなものです。
fetch(url)
.then((resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp.json();
} else {
// This does not work, since the Promise returned by `json()` is never fulfilled
return Promise.reject(resp.json());
}
})
.catch((error) => {
// Do something with the error object
}
// This does not work, since the Promise returned by `json()` is never fulfilled return Promise.reject(resp.json());
さて、resp.json
promise willが満たされ、Promise.reject
のみが待機せず、すぐに拒否しますwith with promise。
私はあなたがむしろ次のことをしたいと思います:
fetch(url).then((resp) => {
let json = resp.json(); // there's always a body
if (resp.status >= 200 && resp.status < 300) {
return json;
} else {
return json.then(Promise.reject.bind(Promise));
}
})
(または、明示的に書かれた)
return json.then(err => {throw err;});
response.ok
に依存し、.json()
によって返されるPromise
の代わりに基礎となるJSONデータを使用する、よりクリーンなアプローチを次に示します。
function myFetchWrapper(url) {
return fetch(url).then(response => {
return response.json().then(json => {
return response.ok ? json : Promise.reject(json);
});
});
}
// This should trigger the .then() with the JSON response,
// since the response is an HTTP 200.
myFetchWrapper('http://api.openweathermap.org/data/2.5/weather?q=Brooklyn,NY').then(console.log.bind(console));
// This should trigger the .catch() with the JSON response,
// since the response is an HTTP 400.
myFetchWrapper('https://content.googleapis.com/youtube/v3/search').catch(console.warn.bind(console));
Jeff Posnick の上記の解決策はそれを行うための私のお気に入りの方法ですが、ネストはかなりingいです。
より新しいasync/await構文を使用すると、すぐに混乱する可能性のあるいネストなしで、より同期的な方法で実行できます。
async function myFetchWrapper(url) {
const response = await fetch(url);
const json = await response.json();
return response.ok ? json : Promise.reject(json);
}
これが機能するのは、 非同期関数は常にプロミスを返す であり、JSONを取得したら、応答ステータスに基づいてそれを返す方法を決定できるからです( response.ok を使用) 。
ジェフの答えと同じ方法でエラー処理を行うか、try/catch、または エラー処理の高階関数 を使用することもできます。
const url = 'http://api.openweathermap.org/data/2.5/weather?q=Brooklyn,NY'
// Example with Promises
myFetchWrapper(url)
.then((res) => ...)
.catch((err) => ...);
// Example with try/catch (presuming wrapped in an async function)
try {
const data = await myFetchWrapper(url);
...
} catch (err) {
throw new Error(err.message);
}
また、読む価値があります MDN-フェッチが成功したことを確認する これを行う必要がある理由は、本質的にフェッチ要求はネットワークエラーで拒否するだけで、404を取得することはネットワークエラーではありません。