2012-07-12 3 views
14

फ़ंक्शन की वापसी में देरी करने के लिए मैं jQuery डिफ्रैड का सही तरीके से उपयोग कैसे कर सकता हूं जब तक कि फ़ंक्शन पूर्ण में एसिंक कॉल न हो + वापसी मूल्य प्राप्त करें?jQuery स्थगित: कार्य पूर्ण होने के दौरान एसिंक कॉल तक फ़ंक्शन की वापसी में देरी करने के लिए उपयोग करें + वापसी मूल्य प्राप्त करें

function getFields(page) 
{ 
    var dff = $.Deferred(); 
    result = {}; 
    $.ajax(//the async call 
    { 
     url: page, 
     success: 
     function (data) 
     { 
      //work out values for field1 & field 2 from data here 
      result = 
      { 
      'field1' : field1, 
      'field2' : field2 
      }; 
     }, 
     complete: 
     function() 
     { 
      dff.resolve(result); //my attempt to return the result 
     } 
    } 
); 
    return dff.promise(); 
} 

मैं इस {: "मान 1", "field2": "फ़ील्ड 1" "मान 2"} प्रिंट करना चाहते हैं:

यह मेरे वर्तमान कोड है

var result = getFields('http://something'); 
console.log(JSON.stringify(result)); 

हालांकि, मूल्य परिणाम एक jQuery ऑब्जेक्ट प्रतीत होता है - इसलिए मैं कुछ गलत कर रहा हूं, लेकिन क्या?

धन्यवाद!


पीएस नौसिखिया प्रश्न के लिए खेद है, मैं पहली बार स्थगित लोगों का उपयोगकर्ता हूं, इसलिए मैं अभी भी बुनियादी अवधारणाओं को समझ रहा हूं।

उत्तर

12

अपने getFields समारोह की वापसी में देरी करने के गलत पर AJAX async गुण सेट करने के लिए किया जाएगा एक ही रास्ता:

var ajaxPromise = $.ajax(
    { 
     url: page, 
     async: false // make the call synchronous 
    } 
); 

लेकिन jQuery प्रलेखन लिखते हैं कि इस 1.8 के बाद से हटा दिया गया है (यानी इस्तेमाल होता है यह है हतोत्साहित)।

डिफरर्ड AJAX सिंक्रोनस नहीं बनाते हैं, इसके बजाय वे कॉलबैक और असीमित तरीकों के साथ काम करना आसान बनाते हैं।

function getFields(page) 
{ 
    var ajaxPromise = $.ajax(//the async call 
    { 
     url: page 
    } 
); 

    var dff = $.Deferred(); 
    ajaxPromise.then(function(data){ 

    // Possibly access the loaded data in this function. 
    var result = { 
     'field1' : field1, 
     'field2' : field2 
    }; 

    // Notify listeners that the AJAX call completed successfully. 
    dff.resolve(result); 

    }, function(){ 
    // Something went wrong - notify listeners: 
    dff.reject(/* possibly pass information about the error */); 
    }); 

    return dff.promise(); 
} 

तो इस तरह वादा वस्तु का उपयोग करें::

मैं क्या आप इसे करने की कोशिश कर रहे हैं क्या बेहतर काम कर सकते हैं इस तरह कुछ करने के लिए की बता सकते हैं

var fieldPromise = getFields('http://something'); 
fieldPromise.done(function(result){ 
    console.log(JSON.stringify(result)); 
}); 

ध्यान दें कि getFields तुरंत Promise ऑब्जेक्ट देता है लेकिन परिणाम को लॉग आउट करने से पहले आपको हल करने का वादा करना होगा।

+0

@ Sly_caridnal: +1 और जांच - महान स्पष्टीकरण! – bguiz

+0

ओह, अच्छा ... लपेटना 'dff.resolve (डेटा);' एक 'सेटटाइमआउट' में धीमी AJAX कॉल अनुकरण करने का एक तेज़ और आसान तरीका है (क्योंकि मैं जो परीक्षण कर रहा हूं वह पहले या बाद में खत्म नहीं होता है दूसरा AJAX कॉल) – Izkata

+0

वास्तव में एक तरीका है: 'getFields (पेज) 'फ़ंक्शन का रिटर्न स्टेटमेंट' रिटर्न dff.promise()। getState() == 'हल किया गया' 'बदलें, यह हल हो जाएगा या अस्वीकार होने तक रोक देगा। बेशक आप केवल वादे ऑब्जेक्ट को वापस कर सकते हैं और राज्य को कहीं और जांच सकते हैं। – shuangwhywhy

6

यहां स्थगित करने का मूल विचार है: आपको एक वस्तु वापस कर दी गई है, और आप इसका उपयोग उन कार्यों को परिभाषित करने के लिए कर सकते हैं जिन्हें वापसी मूल्य वापस आता है। तो अगर आप की तरह कुछ कर सकता है:

function getFields(page) 
{ 
    return $.ajax(page); 
} 

तो फिर तुम इसे कहते और कहा जा करने के लिए एक समारोह निर्दिष्ट कर सकते हैं जब एक्सएचआर कॉल पूरे करता है:

var jqXHR = getFields("/path/to/call"); 
jqXHR.done(function (data) { alert(JSON.stringify(data); }); 

वस्तु, chainable है, ताकि आप केवल यह कर सकते हैं :

getFields("/path/to/call") 
    .done(function (data) { alert(JSON.stringify(data); }); 

ध्यान दें कि jqXHR वस्तु $.ajax से लौटे, एक स्थगित संगत वस्तु है, इसलिए आप http://api.jquery.com/category/deferred-object/ पर दस्तावेज़ पढ़ सकते हैं।

function getFields() 
{ 
    var df = $.Deferred(); 
    window.setTimeout(function() { 
     df.resolve({field1: "value1", field2: "value2"}); 
    }, 1000); 
    return df.promise(); 
} 

getFields().done(function (data) { console.log(JSON.stringify(data)); }); 

यह वांछित मान एक प्रिंट होगा:

मुझे यकीन है कि आप अपने नमूना कोड से क्या मतलब (क्योंकि यह वास्तव में अजाक्स कॉल का उपयोग नहीं करता है), लेकिन हो सकता है आप कुछ इस तरह का मतलब नहीं कर रहा हूँ इसे चलाने के बाद दूसरा।

संबंधित मुद्दे