[javascript] .json ()이 프라 미스를 반환하는 이유는 무엇입니까?

나는 fetch()최근에 API를 엉망으로 만들고 약간 기발한 것을 발견했습니다.

let url = "http://jsonplaceholder.typicode.com/posts/6";

let iterator = fetch(url);

iterator
  .then(response => {
      return {
          data: response.json(),
          status: response.status
      }
  })
  .then(post => document.write(post.data));
;

post.dataPromise객체를 반환 합니다.
http://jsbin.com/wofulo/2/edit?js,output

그러나 다음과 같이 작성된 경우 :

let url = "http://jsonplaceholder.typicode.com/posts/6";

let iterator = fetch(url);

iterator
  .then(response => response.json())
  .then(post => document.write(post.title));
;

post여기 Object에 제목 속성에 액세스 할 수 있는 표준 이 있습니다.
http://jsbin.com/wofulo/edit?js,output

그래서 내 질문은 : 왜 response.json객체 리터럴에서 약속을 반환하지만 방금 반환되면 값을 반환합니까?



답변

response.json약속을 반환하는 이유는 무엇 입니까?

response모든 헤더가 도착하자마자 수신하기 때문입니다. 호출 .json()은 아직로드되지 않은 http 응답 본문에 대한 또 다른 약속을 제공합니다. JavaScript fetch API의 응답 객체가 약속 인 이유 도 참조하세요 . .

then핸들러 에서 프라 미스를 반환하면 왜 값을 얻 습니까?

그것이 약속이 작동하는 방식 이기 때문 입니다. 콜백에서 프라 미스를 반환하고이를 채택하는 기능은 가장 관련성이 높은 기능이며 중첩없이 체인화 할 수 있습니다.

당신이 사용할 수있는

fetch(url).then(response => 
    response.json().then(data => ({
        data: data,
        status: response.status
    })
).then(res => {
    console.log(res.status, res.data.title)
}));

또는 이전 약속에 액세스 하는 다른 접근 방식 은 json 본문을 기다린 후 응답 상태를 얻기 위해 .then () 체인 을 발생시킵니다.


답변

이 차이는 fetch()특히 약속의 동작 때문 입니다.

.then()콜백이 추가 반환 Promise, 다음 .then()체인의 콜백은 본질적으로, 그 약속에 바인딩의 결의를 수신하거나 이행과 가치를 거부합니다.

두 번째 스 니펫은 다음과 같이 작성할 수도 있습니다.

iterator.then(response =>
    response.json().then(post => document.write(post.title))
);

이 양식과 귀하의 양식 모두에서의 값은 post에서 반환 된 Promise에 의해 제공됩니다 response.json().


Object하지만 plain을 반환하면 다음 .then()과 유사하게 성공적인 결과를 고려하고 즉시 해결됩니다.

iterator.then(response =>
    Promise.resolve({
      data: response.json(),
      status: response.status
    })
    .then(post => document.write(post.data))
);

post이 경우는 단순히 Object당신이 만든 것이며 Promise, 그 data속성 을 유지 합니다. 그 약속이 성취되기를 기다리는 것은 아직 불완전합니다.


답변

또한 설명하신이 특정 시나리오를 이해하는 데 도움이 된 것은 Promise API 문서입니다 . 특히 then메서드에서 반환 된 promise처리기 fn이 반환 하는 내용에 따라 다르게 해결 되는 방법을 설명 합니다.

핸들러 함수 :

  • 값을 반환하고, 반환 된 promise는 반환 된 값을 값으로 사용하여 해결됩니다.
  • 오류가 발생하면 반환 된 promise는 해당 값으로 오류가 발생하여 거부됩니다.
  • 이미 해결 된 promise를 반환하고, 그때 반환 된 promise는 해당 promise의 값을 값으로 사용하여 해결됩니다.
  • 이미 거부 된 약속을 반환하고, 반환 된 약속은 해당 약속의 값을 값으로 사용하여 거부됩니다.
  • 또 다른 보류중인 promise 객체를 반환합니다. 그때까지 반환 된 promise의 해결 / 거부는 핸들러가 반환 한 promise의 해결 / 거부 이후입니다. 또한 그때 반환 된 promise의 값은 핸들러가 반환 한 promise의 값과 동일합니다.

답변

위의 답변 외에도 json으로 인코딩 된 오류 메시지를 수신하는 API에서 500 시리즈 응답을 처리하는 방법이 있습니다.

function callApi(url) {
  return fetch(url)
    .then(response => {
      if (response.ok) {
        return response.json().then(response => ({ response }));
      }

      return response.json().then(error => ({ error }));
    })
  ;
}

let url = 'http://jsonplaceholder.typicode.com/posts/6';

const { response, error } = callApi(url);
if (response) {
  // handle json decoded response
} else {
  // handle json decoded 500 series response
}


답변