तब जावास्क्रिप्ट में क्या कार्य करता है?


275

मुझे ऐसा कोड दिखाई दे रहा है जो दिखता है:

myObj.doSome("task").then(function(env) {
    // logic
});

कहाँ then()से आता है?


8
अद्यतन किया गया: मुझे पता चला कि यह कॉमनजस
के पेल

जवाबों:


348

जावास्क्रिप्ट में अतुल्यकालिक कॉल से निपटने का पारंपरिक तरीका कॉलबैक के साथ रहा है। कहें कि हमें अपना एप्लिकेशन सेट करने के लिए सर्वर पर एक के बाद एक तीन कॉल करने थे। कॉलबैक के साथ, कोड कुछ इस तरह दिख सकता है (सर्वर कॉल करने के लिए xhrGET फ़ंक्शन मानकर):

// Fetch some server configuration
    xhrGET('/api/server-config', function(config) {
        // Fetch the user information, if he's logged in
        xhrGET('/api/' + config.USER_END_POINT, function(user) {
            // Fetch the items for the user
            xhrGET('/api/' + user.id + '/items', function(items) {
                // Actually display the items here
            });
        });
    });

इस उदाहरण में, हम पहले सर्वर कॉन्फ़िगरेशन प्राप्त करते हैं। फिर उसके आधार पर, हम वर्तमान उपयोगकर्ता के बारे में जानकारी प्राप्त करते हैं, और फिर वर्तमान उपयोगकर्ता के लिए आइटम की सूची प्राप्त करते हैं। प्रत्येक xhrGET कॉल एक कॉलबैक फ़ंक्शन लेता है जिसे सर्वर द्वारा प्रतिक्रिया देने पर निष्पादित किया जाता है।

अब निश्चित रूप से हमारे पास घोंसले के अधिक स्तर हैं, कोड को पढ़ना, डिबग करना, बनाए रखना, अपग्रेड करना, और मूल रूप से काम करना कठिन है। यह आमतौर पर कॉलबैक नरक के रूप में जाना जाता है। इसके अलावा, अगर हमें त्रुटियों को संभालने की आवश्यकता है, तो हमें संभवतः किसी अन्य फ़ंक्शन को प्रत्येक xhrGET कॉल में पास करने की आवश्यकता है ताकि यह बता सकें कि त्रुटि के मामले में उसे क्या करना है। यदि हम केवल एक सामान्य त्रुटि हैंडलर चाहते हैं, तो यह संभव नहीं है।

प्रॉमिस एपीआई को इस घोंसले की समस्या और त्रुटि से निपटने की समस्या को हल करने के लिए डिज़ाइन किया गया था।

वादा एपीआई निम्नलिखित का प्रस्ताव:

  1. प्रत्येक एसिंक्रोनस कार्य किसी promiseऑब्जेक्ट को लौटाएगा ।
  2. प्रत्येक promiseऑब्जेक्ट में एक thenफ़ंक्शन होगा जो दो तर्क, एक success हैंडलर और एक errorहैंडलर ले सकता है।
  3. अतुल्यकालिक कार्य समाप्त होने के बाद, फ़ंक्शन में सफलता या त्रुटि हैंडलर को thenकेवल एक बार कहा जाएगा ।
  4. thenसमारोह भी एक वापस आ जाएगी promise, एकाधिक कॉल चेनिंग अनुमति देने के लिए।
  5. प्रत्येक हैंडलर (सफलता या त्रुटि) एक वापस कर सकता है value, जिसे अगले फ़ंक्शन को एस argumentकी श्रृंखला में, एक के रूप में पारित किया जाएगा promise
  6. यदि कोई हैंडलर रिटर्न करता है promise(दूसरा अतुल्यकालिक अनुरोध करता है), तो अगला हैंडलर (सफलता या त्रुटि) उस अनुरोध के समाप्त होने के बाद ही कहा जाएगा।

इसलिए पिछला उदाहरण कोड वादों और $httpसेवा (AngularJs में) का उपयोग करते हुए निम्नलिखित की तरह कुछ का अनुवाद कर सकता है :

$http.get('/api/server-config').then(
    function(configResponse) {
        return $http.get('/api/' + configResponse.data.USER_END_POINT);
    }
).then(
    function(userResponse) {
        return $http.get('/api/' + userResponse.data.id + '/items');
    }
).then(
    function(itemResponse) {
        // Display items here
    }, 
    function(error) {
        // Common error handling
    }
);

सफलता और त्रुटि का प्रचार करना

चेनिंग वादे एक बहुत शक्तिशाली तकनीक है जो हमें बहुत सारी कार्यक्षमता को पूरा करने की अनुमति देती है, जैसे कि एक सेवा में सर्वर कॉल करना, डेटा के कुछ पोस्टप्रोसेसिंग करना, और फिर नियंत्रक को संसाधित डेटा वापस करना। लेकिन जब हम promiseजंजीरों के साथ काम करते हैं, तो कुछ बातों को ध्यान में रखना आवश्यक है।

promiseतीन वादों, पी 1, पी 2, और पी 3 के साथ निम्नलिखित काल्पनिक श्रृंखला पर विचार करें । प्रत्येक के promiseपास एक सफल हैंडलर और एक त्रुटि हैंडलर है, इसलिए पी 1 के लिए एस 1 और ई 1, पी 2 के लिए एस 2 और ई 2 और पी 3 के लिए एस 3 और ई 3 है:

xhrCall()
  .then(S1, E1) //P1
  .then(S2, E2) //P2
  .then(S3, E3) //P3

चीजों के सामान्य प्रवाह में, जहां कोई त्रुटि नहीं है, आवेदन S1, S2 और अंत में, S3 के माध्यम से प्रवाह होगा। लेकिन वास्तविक जीवन में, चीजें कभी भी सहज नहीं होती हैं। P1 में एक त्रुटि हो सकती है, या P2 में त्रुटि हो सकती है, E1 या E2 को ट्रिगर किया जा सकता है।

निम्नलिखित मामलों पर विचार करें:

• हम पी 1 में सर्वर से एक सफल प्रतिक्रिया प्राप्त करते हैं, लेकिन लौटाया गया डेटा सही नहीं है, या सर्वर पर कोई डेटा उपलब्ध नहीं है (खाली सरणी सोचें)। ऐसे मामले में, अगले वादा पी 2 के लिए, यह त्रुटि हैंडलर ई 2 को ट्रिगर करना चाहिए।

• हमें E2, ट्रिगर 2 के लिए एक त्रुटि मिलती है। लेकिन हैंडलर के अंदर, हमारे पास कैश से डेटा है, यह सुनिश्चित करते हुए कि एप्लिकेशन सामान्य रूप से लोड हो सकता है। उस स्थिति में, हम यह सुनिश्चित करना चाहते हैं कि E2 के बाद, S3 कहा जाता है।

इसलिए हर बार जब हम एक सफलता या एक त्रुटि हैंडलर लिखते हैं, तो हमें एक कॉल करने की आवश्यकता होती है - हमारे वर्तमान फ़ंक्शन को देखते हुए, क्या यह वादे की श्रृंखला में अगले हैंडलर के लिए सफलता या विफलता है?

यदि हम श्रृंखला में अगले वादे के लिए सफलता हैंडलर को ट्रिगर करना चाहते हैं, तो हम सफलता या त्रुटि हैंडलर से केवल एक मूल्य वापस कर सकते हैं

यदि दूसरी ओर, हम श्रृंखला में अगले वादे के लिए त्रुटि हैंडलर को ट्रिगर करना चाहते हैं, तो हम ऐसा कर सकते हैं कि किसी deferredवस्तु का उपयोग करके और उसकी reject()विधि को कॉल करके

अब आस्थगित वस्तु क्या है?

JQuery में आस्थगित ऑब्जेक्ट्स उस कार्य की एक इकाई का प्रतिनिधित्व करते हैं जो बाद में पूरा हो जाएगा, आमतौर पर अतुल्यकालिक रूप से। एक बार कार्य की इकाई पूरी हो जाने के बाद, deferredऑब्जेक्ट को हल या विफल करने के लिए सेट किया जा सकता है।

एक deferredवस्तु में एक promiseवस्तु होती है। promiseऑब्जेक्ट के माध्यम से आप निर्दिष्ट कर सकते हैं कि कार्य की इकाई के पूरा होने पर क्या होना है। आप promiseऑब्जेक्ट पर कॉलबैक फ़ंक्शन सेट करके ऐसा करते हैं ।

जेकरी में आस्थगित वस्तुएं: https://api.jquery.com/jquery.deferred/

AngularJs में आस्थगित वस्तुएं: https://docs.angularjs.org/api/ng/service/ $ q


3
बहुत अच्छा लिखा है। इससे मुझे वादों को नाकाम करने में मदद मिली है।
Ju66ernaut

क्या त्रुटि हैंडलर, दूसरा पैरामीटर, हमेशा वैकल्पिक है?
1.21 गीगावाट

यह अब तक का सबसे अच्छा जवाब है जो मैंने देखा है!
इमाम बक्स

78

तब () फ़ंक्शन "जावास्क्रिप्ट वादों" से संबंधित है जो कुछ पुस्तकालयों या फ्रेमवर्क जैसे कि jQuery या AngularJS में उपयोग किए जाते हैं।

एक वादा अतुल्यकालिक संचालन से निपटने के लिए एक पैटर्न है। वादा आपको "तब" नामक एक विधि को कॉल करने की अनुमति देता है जो आपको कॉलबैक के रूप में उपयोग करने के लिए फ़ंक्शन (एस) को निर्दिष्ट करने देता है।

अधिक जानकारी के लिए देखें: http://wildermuth.com/2013/8/3/JavaScript_Promises

और कोणीय वादों के लिए: http://liamkaufman.com/blog/2013/09/09/using-angularjs-promises/


4
इसलिए यह एक कॉलबैक की तरह है जो कार्य पूरा होने पर निष्पादित होता है? यह कैसे अलग है
मुहम्मद उमर

3
जावास्क्रिप्ट वादे : में अन्य टिप्पणी कहते हैं A promise can only succeed or fail once, औरIf a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called
जिओ

इसके अलावा, प्रोमिस नगेट्स बताते हैं कि कैसे उपयोग promiseकिया जाए और इसके साथ क्या किया जाएगाcallback
जिओ

पहले पृष्ठ पर, कोड के लापता होने (बड़े सफेद रिक्त स्थान) के अंश हैं। अधिकांश लोग तत्व का निरीक्षण करने के बारे में सोचेंगे और नीचे दिए गए फ़िडेल के URL को ढूंढ पाएंगे। यह संदेश बाकी के लिए है
फ़िडल्स

1
@MuhammadUmer: इस stackoverflow.com/a/31453579/1350476 (सिड द्वारा उत्तर) को
पढ़ें

32

मेरी जानकारी के लिए, (इस लेखन के समय) कोई अंतर्निहित then()पद्धति नहीं है javascript

ऐसा प्रतीत होता है कि यह जो कुछ भी है वह doSome("task")लौटाने की विधि है then

यदि आप doSome()कंसोल के रिटर्न परिणाम को लॉग इन करते हैं , तो आपको जो वापस लौटा था उसके गुणों को देखने में सक्षम होना चाहिए।

console.log( myObj.doSome("task") ); // Expand the returned object in the
                                     //   console to see its properties.

अद्यतन (ECMAScript6 के अनुसार) : -

.then()समारोह शुद्ध जावास्क्रिप्ट को शामिल किया गया है।

यहाँ मोज़िला प्रलेखन से ,

तत्कालीन () विधि एक वादा लौटाती है। यह दो तर्क लेता है: वादे की सफलता और विफलता के मामलों के लिए कॉलबैक फ़ंक्शन।

वादा वस्तु, बदले में, के रूप में परिभाषित किया गया है

वादा वस्तु का उपयोग आस्थगित और अतुल्यकालिक गणनाओं के लिए किया जाता है। एक वादा एक ऑपरेशन का प्रतिनिधित्व करता है जो अभी तक पूरा नहीं हुआ है, लेकिन भविष्य में उम्मीद है।

यही है, Promiseएक मूल्य के लिए प्लेसहोल्डर के रूप में कार्य जो अभी तक गणना नहीं है, लेकिन भविष्य में हल किया जाएगा। और .then()फ़ंक्शन को प्रोमिस पर हल किए जाने वाले फ़ंक्शन को जोड़ने के लिए उपयोग किया जाता है जब इसे हल किया जाता है - या तो सफलता या विफलता के रूप में।


12
.thenतब बिल्ट-इन बैक नहीं था , लेकिन ES6 में अब मूल वादे आने लगे हैं: html5rocks.com/en/tutorials/es6/promises
janfoeh

इस उत्तर के लिए धन्यवाद, मैं कुछ शांत वादा कॉलबैक की उम्मीद कर रहा था लेकिन यह 'फिर' नामक एक वास्तविक फ़ंक्शन निकला।
स्पार्टिकस

15

यहाँ एक चीज है जो मैंने अपने लिए बनाई है ताकि यह पता चले कि चीजें कैसे काम करती हैं। मुझे लगता है कि अन्य लोग भी इस ठोस उदाहरण को उपयोगी पा सकते हैं:

doit().then(function() { log('Now finally done!') });
log('---- But notice where this ends up!');

// For pedagogical reasons I originally wrote the following doit()-function so that 
// it was clear that it is a promise. That way wasn't really a normal way to do 
// it though, and therefore Slikts edited my answer. I therefore now want to remind 
// you here that the return value of the following function is a promise, because 
// it is an async function (every async function returns a promise). 
async function doit() {
  log('Calling someTimeConsumingThing');
  await someTimeConsumingThing();
  log('Ready with someTimeConsumingThing');
}

function someTimeConsumingThing() {
  return new Promise(function(resolve,reject) {
    setTimeout(resolve, 2000);
  })
}

function log(txt) {
  document.getElementById('msg').innerHTML += txt + '<br>'
}
<div id='msg'></div>


5

यहाँ एक छोटा JS_Fiddle है।

फिर एक विधि कॉलबैक स्टैक है जो एक वादे के हल के बाद उपलब्ध है यह jQuery की तरह पुस्तकालय का हिस्सा है लेकिन अब यह देशी जावास्क्रिप्ट में उपलब्ध है और नीचे विस्तार से बताया गया है कि यह कैसे काम करता है

आप मूल जावास्क्रिप्ट में एक वादा कर सकते हैं: जैसे कि jQuery में वादे हैं, हर वादे को स्टैक किया जा सकता है और फिर कॉलबैक को अस्वीकार और अस्वीकार के साथ बुलाया जा सकता है, यह है कि आप अतुल्यकालिक कॉल को कैसे चेन कर सकते हैं।

मैंने बैट्री चार्जिंग स्टेटस पर MSDN डॉक्स से फोर्क और एडिट किया है।

यह क्या पता लगाने की कोशिश करता है कि उपयोगकर्ता लैपटॉप या डिवाइस बैटरी चार्ज कर रहा है या नहीं। उसके बाद कॉल किया जाता है और आप अपने कार्य को सफलता के बाद कर सकते हैं।

navigator
    .getBattery()
    .then(function(battery) {
       var charging = battery.charging;
       alert(charging);
    })
    .then(function(){alert("YeoMan : SINGH is King !!");});

एक और es6 उदाहरण

function fetchAsync (url, timeout, onData, onError) {
    
}
let fetchPromised = (url, timeout) => {
    return new Promise((resolve, reject) => {
        fetchAsync(url, timeout, resolve, reject)
    })
}
Promise.all([
    fetchPromised("http://backend/foo.txt", 500),
    fetchPromised("http://backend/bar.txt", 500),
    fetchPromised("http://backend/baz.txt", 500)
]).then((data) => {
    let [ foo, bar, baz ] = data
    console.log(`success: foo=${foo} bar=${bar} baz=${baz}`)
}, (err) => {
    console.log(`error: ${err}`)
})

परिभाषा :: तब एसिंक्रोनस कॉलबैक को हल करने के लिए एक विधि का उपयोग किया जाता है

इसे ES6 में पेश किया गया है

कृपया उचित दस्तावेज यहां Es6 वादों का पता लगाएं


आपका जवाब वास्तव में सवाल का जवाब नहीं देता है। यह केवल एपीआई उपयोग का एक उदाहरण प्रदान करता है बिना यह बताए कि कहां से thenआता है और यह कैसे काम करता है। आपको उन विवरणों को प्रदान करने के लिए अपने उत्तर में सुधार करना चाहिए।
डिडियर एल

@TarandeepSingh - पहले तो वह कथन जिसमें आप बैटरी की स्थिति के बारे में सचेत करते हैं, कोई वादा वस्तु वापस नहीं की जाती है। फिर दूसरे का क्या उपयोग है
मोहित जैन

@MohitJain यह प्रदर्शित करता है कि यदि आपके पास कोई नया वादा नहीं है तो भी आप कई कॉलबैक कर सकते हैं। चूंकि, Promise.all के साथ कई कॉल भी किए जा सकते हैं।
तरनदीप सिंह

आप " विधि कॉलबैक स्टैक " से क्या मतलब है ?
बर्गी

4

मुझे संदेह है कि doSome ने इसे लौटा दिया है, जो कि myObj है, जिसमें तत्कालीन पद्धति भी है। मानक विधि जंजीर ...

यदि doSome इसे वापस नहीं कर रहा है, तो उस वस्तु का होना जिस पर doSome को निष्पादित किया गया था, बाकी का आश्वासन दिया गया है कि यह किसी वस्तु को तब से वापस कर रहा है ...

जैसा कि @patrick बताते हैं, मानक js के लिए तब () नहीं है


1
मुझे संदेह है कि कुछ लोगों ने इसे लौटाया - कुछ भी लागू नहीं होता है / ऐसे संदेह को उचित ठहराते हैं
सलाथिल जीनस

1

doSome ("कार्य") एक वादा वस्तु वापस करना चाहिए, और उस वादे में हमेशा एक तत्कालीन कार्य होता है।

promise.then(function(env) {
    // logic
}); 

और आप जानते हैं कि यह केवल सदस्य कार्य के लिए एक साधारण कॉल है।


1

.then Async फ़ंक्शन में एक वादा देता है।

अच्छा उदाहरण होगा:

var doSome = new Promise(function(resolve, reject){
    resolve('I am doing something');
});

doSome.then(function(value){
    console.log(value);
});

इसमें एक और तर्क जोड़ने के लिए, आप reject('I am the rejected param')कॉल फंक्शन भी जोड़ सकते हैं और इसे कंसोल कर सकते हैं।


0

इस मामले then()में विधि द्वारा लौटाए गए ऑब्जेक्ट का एक वर्ग तरीका है doSome()


0

".Then ()" फ़ंक्शन वाइडलाइन का उपयोग विंडोज 8 स्टोर ऐप्स के लिए एसिंकोनोरस प्रोग्रामिंग में प्रस्तावित वस्तुओं के लिए किया जाता है। जहाँ तक मैंने समझा कि यह कॉलबैक की तरह काम करता है।

इस वृत्तचित्र में विवरण खोजें http://msdn.microsoft.com/en-us/library/windows/apps/hh700330.aspx

क्योंकि यह किसी अन्य परिभाषित कार्य के लिए भी नाम हो सकता है।


-1

एक और उदाहरण:

new Promise(function(ok) {
   ok( 
      /* myFunc1(param1, param2, ..) */
   )
}).then(function(){
     /* myFunc1 succeed */
     /* Launch something else */
     /* console.log(whateverparam1) */
     /* myFunc2(whateverparam1, otherparam, ..) */
}).then(function(){
     /* myFunc2 succeed */
     /* Launch something else */
     /* myFunc3(whatever38, ..) */
})

एरो फ़ंक्शंस शॉर्टहैंड का उपयोग कर एक ही तर्क:

new Promise((ok) =>
   ok( 
      /* myFunc1(param1, param2, ..) */
)).then(() =>
     /* myFunc1 succeed */
     /* Launch something else */
     /* Only ONE call or statment can be made inside arrow functions */
     /* For example, using console.log here will break everything */
     /* myFunc2(whateverparam1, otherparam, ..) */
).then(() =>
     /* myFunc2 succeed */
     /* Launch something else */
     /* Only ONE call or statment can be made inside arrow functions */
     /* For example, using console.log here will break everything */
     /* myFunc3(whatever38, ..) */
)


-4

मुझे लगभग 8 साल देर हो चुकी है, खैर ... वैसे भी, मैं वास्तव में नहीं जानता कि तब () क्या करता है, लेकिन शायद एमडीएन का जवाब हो सकता है। वास्तव में, मैं वास्तव में इसे थोड़ा और समझ सकता हूं।

यह आपको सभी जानकारी (उम्मीद) दिखाएगा, आपको आवश्यकता है। जब तक किसी ने इस लिंक को पोस्ट नहीं किया। https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

प्रारूप वादा किया गया है ।prototyp.then () वादा और प्रोटोटाइप तरह तरह के चर हैं, लेकिन जावास्क्रिप्ट में चर की तरह नहीं हैं, मेरा मतलब है कि अन्य चीजें जैसे नेविगेटर.गेटबैटरी () की तरह वहां जाती हैं। तब (जहां यह वास्तव में मौजूद है, लेकिन है) वेब पर बमुश्किल उपयोग किया जाता है, यह एक डिवाइस की बैटरी के बारे में स्थिति दिखाता है, यदि आप उत्सुक हैं, तो एमडीएन पर अधिक जानकारी और अधिक।

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