.Json () neden bir söz verir?


116

fetch()Son zamanlarda api ile uğraşıyorum ve biraz tuhaf olan bir şey fark ettim.

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.databir Promisenesne döndürür . http://jsbin.com/wofulo/2/edit?js,output

Ancak şu şekilde yazılırsa:

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

let iterator = fetch(url);

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

postObjectbaşlık niteliğine erişebileceğiniz bir standart . http://jsbin.com/wofulo/edit?js,output

Öyleyse sorum şu: neden response.jsonbir nesnenin değişmez bir sözünü döndürür, ancak sadece döndürülürse değeri döndürür?


1
response.json()Yanıt geçerli JSON değilse sözün reddedilebileceğini düşündüğünüzde bu mantıklıdır .
ssube

1
Değer, değeri response.json () 'a iletme vaadi çözümlendiğinden döndürülür. Şimdi değer o zaman yöntemde mevcuttur.
Jose Hermosilla Rodrigo

Yanıtlar:


168

Neden response.jsonbir sözü geri veriyor?

Çünkü responsetüm başlıklar ulaşır ulaşmaz alırsınız . Çağrı .json(), size henüz yüklenmemiş olan http yanıtının gövdesi için başka bir söz verir. Ayrıca bkz . JavaScript'ten gelen yanıt nesnesi neden bir vaattir? .

thenİşleyiciden sözümü geri verirsem neden değeri alıyorum ?

Çünkü sözler böyle işler . Sözleri geri aramadan geri verme ve onları benimseme becerisi, en alakalı özelliğidir ve onları iç içe geçmeden zincirlenebilir hale getirir.

Kullanabilirsiniz

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

veya önceki vaatlere erişim yaklaşımlarından herhangi biri, json gövdesini bekledikten sonra yanıt durumunu almak için bir. sonra () zinciriyle sonuçlanır .


Verilerin bir Söz kullanarak geri dönmesini bekleyemem ve geldiğinde onu json'a dönüştürmem garip görünüyor? Ya da belki bu durumda JSON.parse()yerine kullanabilirim res.json()??
Kokodoko

8
@Kokodoko res.json()temelde için bir kısayol res.text().then(JSON.parse). Her ikisi de bir söz kullanarak verileri bekler ve json'u ayrıştırır.
Bergi

@Bergi, merhaba, özür dilerim, bazı karışıklıklarla karşılaştım, yani, daha sonra (res => res.json ()) kullanarak JSON almak için başka bir istek gönderiyoruz?
mirzhal

1
@mirzhal Hayır, başka istek yok. Sadece yanıtın geri kalanını (eşzamansız olarak!) Okuyor.
Bergi

14

Bu fark, fetch()özellikle Promises'in davranışından kaynaklanmaktadır .

Bir .then()geri arama bir ek döndürdüğünde , zincirdeki bir Promisesonraki .then()geri arama, esas olarak söz konusu Promise'a bağlıdır ve kararını veya reddinin yerine getirilmesini ve değerini alır.

2. pasaj şu şekilde de yazılabilirdi:

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

Hem bu formda hem de sizin formunuzda, değeri postgeri dönen Promise tarafından sağlanır response.json().


Düz bir geri döndüğünüzde Object, yine de, .then()başarılı bir sonuç olduğunu düşünür ve şuna benzer şekilde hemen kendini çözer:

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

postbu durumda, kendi özelliğinde Objecta tutan sizin yarattığınızdır . Bu vaadin yerine getirilmesi için bekleyiş hala eksik.Promisedata


7

Ayrıca, tarif ettiğiniz bu özel senaryoyu anlamama yardımcı olan şey Promise API dokümantasyonudur , özellikle de söz konusu thenyöntem tarafından döndürülen vaatlerin fn işleyicisinin döndürdüğü şeye bağlı olarak nasıl farklı şekilde çözüleceğini açıklar :

işleyici işlevi:

  • bir değer döndürür, daha sonra döndürülen söz, değeri olarak döndürülen değerle çözümlenir;
  • bir hata atarsa, tarafından döndürülen söz, değeri olarak atılan hatayla reddedilir;
  • zaten çözülmüş bir söz verirse, o zamana kadar geri dönen söz, o sözün değeri olarak sözün değeriyle çözümlenir;
  • Zaten reddedilmiş bir söz verirse, o zamana kadar geri dönen söz, değeri olarak o sözün değeriyle reddedilir.
  • başka bir bekleyen vaat nesnesini döndürürse, o zamana kadar iade edilen vaatin çözümlenmesi / reddi, işleyici tarafından iade edilen vaatin çözülmesinin / reddinin ardından olacaktır. Ayrıca, o zamana kadar döndürülen sözün değeri, işleyicinin döndürdüğü sözün değeriyle aynı olacaktır.

5

Yukarıdaki yanıtlara ek olarak, json'da kodlanmış bir hata iletisi aldığınız API'nizden 500 serisi bir yanıtı nasıl işleyebileceğiniz aşağıda açıklanmıştır:

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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.