क्यों .json () एक वादा वापस करता है?


115

मैं fetch()हाल ही में एपीआई के साथ खिलवाड़ कर रहा हूं , और कुछ देखा जो थोड़ा सा विचित्र था।

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.dataकोई Promiseवस्तु लौटाता है । 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एक वस्तु शाब्दिक में एक वादा क्यों लौटाता है, लेकिन अगर वापस लौटा है तो मान लौटाएं?


1
यह समझ में आता है जब आप मानते हैं कि response.json()वादा अस्वीकार नहीं किया जाता है तो वादा खारिज किया जा सकता है।
ssube

1
मान वापस कर दिया गया है क्योंकि प्रतिसाद को हल कर दिया गया है प्रतिक्रिया में मान को पार कर रहा है। json ()। अब मान तत्कालीन विधि में उपलब्ध है।
जोस हरमोसिला रोड्रिगो

जवाबों:


167

response.jsonएक वादा वापस क्यों करता है ?

क्योंकि आप responseजैसे ही सभी हेडर आए हैं। कॉलिंग .json()आपको http प्रतिक्रिया के निकाय के लिए एक और वादा देता है जिसे अभी तक लोड किया जाना है। यह भी देखें जावास्क्रिप्ट प्रस्ताव एपीआई से प्रतिक्रिया वस्तु क्यों एक वादा है?

यदि मैं thenहैंडलर से वादा वापस करता हूं तो मुझे मूल्य क्यों मिलता है ?

क्योंकि यही वादे काम करते हैं । कॉलबैक से वादे वापस करने और उन्हें अपनाए जाने की क्षमता उनकी सबसे प्रासंगिक विशेषता है, यह उन्हें घोंसले के शिकार के बिना श्रृंखलाबद्ध बनाता है।

आप उपयोग कर सकते हैं

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

या किसी अन्य दृष्टिकोण का उपयोग करने के लिए .then () श्रृंखला में पिछले वादा परिणामों को प्राप्त करने के लिए प्रतिक्रिया स्थिति प्राप्त करने के बाद जसन बॉडी का इंतजार कर रहे हैं।


यह अजीब लगता है कि मैं केवल एक वादा का उपयोग करके डेटा के लिए इंतजार नहीं कर सकता, और जब यह आ गया है तो इसे जसन में बदल दें? या शायद उस मामले में मैं JSON.parse()इसके बजाय सिर्फ इस्तेमाल कर सकता था res.json()??
कोकोडोको

8
@ कोकोडको res.json()मूल रूप से एक शॉर्टकट है res.text().then(JSON.parse)। दोनों एक वादा का उपयोग करते हुए डेटा की प्रतीक्षा करते हैं और जस को पार्स करते हैं।
बर्गी

@Bergi, हाय, क्षमा करें, मुझे कुछ भ्रम का सामना करना पड़ा, जो तब (Res => res.json ()) का उपयोग करके हम JSON प्राप्त करने के लिए एक और अनुरोध भेजते हैं?
मिरज़ल

1
@मीरज़हल नो, कोई अन्य अनुरोध नहीं है। यह बस (asynchronously) पढ़ रहा है बाकी की प्रतिक्रिया।
बेर्गी

14

यह अंतर fetch()विशेष रूप से वादों के व्यवहार के कारण है ।

जब .then()कॉलबैक एक अतिरिक्त रिटर्न देता है Promise, तो .then()श्रृंखला में अगला कॉलबैक अनिवार्य रूप से उस वादे के लिए बाध्य होता है, जो अपने संकल्प को प्राप्त करता है या पूर्ति और मूल्य को अस्वीकार करता है।

दूसरा स्निपेट भी लिखा जा सकता है:

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

इस रूप और आपके दोनों में, का मूल्य postप्रदान किया गया वादा द्वारा लौटाया गया है response.json()


जब आप एक मैदान लौटते हैं Object, हालांकि, यह .then()मानता है कि एक सफल परिणाम और खुद को तुरंत हल करता है:

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

postइस मामले में Objectआप बस बनाया है, जो Promiseअपनी dataसंपत्ति में एक रखती है । उस वादे को पूरा करने का इंतजार अब भी अधूरा है।


7

इसके अलावा, मुझे इस विशेष परिदृश्य को समझने में क्या मदद मिली जो आपने वर्णित किया है प्रॉमिस एपीआई प्रलेखन , विशेष रूप से जहां यह बताता है कि कैसे thenविधि द्वारा लौटाया गया वादा अलग तरीके से हल किया जाएगा जो हैंडलर fn रिटर्न के आधार पर होता है:

यदि हैंडलर फ़ंक्शन:

  • मान लौटाता है, तब तक दिया गया वादा उसके मूल्य के रूप में लौटाए गए मूल्य के साथ हल हो जाता है;
  • एक त्रुटि फेंकता है, तब तक दिया गया वादा उसके मूल्य के रूप में फेंकी गई त्रुटि के साथ अस्वीकृत हो जाता है;
  • पहले से ही हल किए गए वादे को वापस करता है, तब तक दिया गया वादा उस मूल्य के मूल्य के साथ हल हो जाता है;
  • पहले से ही अस्वीकार किए गए वादे को वापस करता है, तब तक लौटाया गया वादा उस मूल्य के मूल्य के साथ अस्वीकृत हो जाता है।
  • किसी अन्य लंबित वादे की वस्तु को लौटाता है, तब तक लौटाए गए वादे का संकल्प / अस्वीकृति हैंडलर द्वारा दिए गए वादे के प्रस्ताव / अस्वीकृति के बाद होगा। साथ ही, तब तक लौटाए गए वादे का मूल्य उसी तरह होगा जैसा कि हैंडलर द्वारा दिए गए वादे का मूल्य है।

5

ऊपर दिए गए उत्तरों के अलावा आप अपने एपीआई से 500 सीरीज़ रिस्पॉन्स को कैसे हैंडल कर सकते हैं, जहां आपको एक त्रुटि संदेश प्राप्त होता है जो कि json में एन्कोडेड है:

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
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.