web-dev-qa-db-ja.com

response.json()およびresponse.statusをフェッチします

これが body.json() を使用してステータスコードを取得する唯一の方法ですか?

let status;

return fetch(url)
    .then((response => {
         status = response.status;
         return response.json()
     })
    .then(response => {
        return {
            response: response,
            status: status
        }
    });

応答フィールドにpromiseを返すため、これは機能しません。

.then((response)=> {return {response: response.json(), status: response.status}})
13
Guy

2番目のthenにはステータスが表示されません。単一のthenで2つのプロパティを取得できます。

json()は新しいPromiseを返すため、その関数の結果のthen内にオブジェクトを作成する必要があります。関数からPromiseを返す場合、Promiseは履行され、履行の結果(この場合はオブジェクト)を返します。

fetch("https://jsonplaceholder.typicode.com/posts/1")
.then(r =>  r.json().then(data => ({status: r.status, body: data})))
.then(obj => console.log(obj));
36
Suren Srapyan

先週、まったく同じ問題に直面しました。 .jsonメソッドは、JSON自体ではなく、JSONにプロミスを返します。応答とJSONの両方に一度にアクセスする場合は、次のようなネストされたクロージャーを使用する必要があります。

fetch(...)
    .then(response => {
        response.json().then(json => {
            // code that can access both here
        })
    })

json promiseに渡されたコールバックは、fetch promiseへのコールバック内で作成されたため、responseへのアクセス権も持ちます。

JSONやエラーのケースを処理する関数を作成し、それをすべてのフェッチに再利用したい場合があります。たとえば、次のようなもの:

function fetchHandler(response) {
    if (response.ok) {
        return response.json().then(json => {
            // the status was ok and there is a json body
            return Promise.resolve({json: json, response: response});
        }).catch(err => {
            // the status was ok but there is no json body
            return Promise.resolve({response: response});
        });

    } else {
        return response.json().catch(err => {
            // the status was not ok and there is no json body
            throw new Error(response.statusText);
        }).then(json => {
            // the status was not ok but there is a json body
            throw new Error(json.error.message); // example error message returned by a REST API
        });
    }
}
7
Domino

最もきれいな方法は、必要な部分でPromise.all()を作成することだと思います。

.then(response => Promise.all([Promise.resolve(response.ok), response.text()]))

次のように短く書くことができます

.then(response => Promise.all([response.ok, response.text()]))

Promiseはすべての結果を含む配列を返します

.then(data => ({ status: data[0], response: data[1] }))

0
blindguy

これを試しましたか?

return fetch(url)
    .then((r)=> {return {response: r.json(), status: r.status}})
0
Drag13