मैं अतुल्यकालिक, अजाक्स अनुरोध के बजाय एक तुल्यकालिक प्रदर्शन करने के लिए jQuery कैसे प्राप्त कर सकता हूं?


1207

मेरे पास एक जावास्क्रिप्ट विजेट है जो मानक विस्तार बिंदु प्रदान करता है। उनमें से एक beforecreateफ़ंक्शन है। falseकिसी आइटम को बनाए जाने से रोकने के लिए इसे वापस करना चाहिए ।

मैंने jQuery का उपयोग करके इस फ़ंक्शन में एक अजाक्स कॉल जोड़ा है:

beforecreate: function (node, targetNode, type, to) {
  jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),

  function (result) {
    if (result.isOk == false) 
        alert(result.message);
  });
}

लेकिन मैं अपने विजेट को आइटम बनाने से रोकना चाहता हूं, इसलिए मुझे falseकॉलबैक में नहीं, मदर-फंक्शन में लौटना चाहिए । क्या jQuery या किसी अन्य इन-ब्राउज़र एपीआई का उपयोग करके एक तुल्यकालिक AJAX अनुरोध करने का एक तरीका है?


30
इसे हल करने का उचित तरीका आपके विजेट के विस्तार बिंदु उपयोग वादों को फिर से लिखना होगा। इस तरह से आप आसानी से एक एसिंक्रोनस एक्शन (जैसे अजाक्स अनुरोध) सेट कर सकते हैं beforecreate
कोस

3
मैं सजक फंक्शन का प्रस्ताव करता हूं। क्या हमारे पास एक पत्र टी है? हां वन्ना, मुझे 3 टी दे दो।
कोडी ओ'डेल

2
@ कोस हाजिर है। यहाँ सिंक XHR की आवश्यकता नहीं है
माइकल वेस्टकोट

1
अगर लोग जावास्क्रिप्ट शुरू करते समय मुझसे 1 टुकड़ा सलाह मांगते हैं, तो मैं कहता हूं: जावास्क्रिप्ट के अतुल्यकालिक चरित्र को गले लगाओ, टी लड़ाई से कोशिश मत करो।
इमैनुएल डिले

3
यह सवाल यह पूछने जैसा है कि "मैं अपने उपयोगकर्ता पासवर्ड को सादे पाठ में कैसे संग्रहीत करूं?" यकीन है कि एक जवाब है, लेकिन यह मत करो।
वेक्टरजॉन

जवाबों:


1165

से jQuery प्रलेखन : आपके द्वारा निर्दिष्ट अतुल्यकालिक होने के लिए विकल्प झूठी एक तुल्यकालिक Ajax अनुरोध प्राप्त करने के लिए। तब आपकी कॉलबैक आपके मदर फंक्शन के बढ़ने से पहले कुछ डेटा सेट कर सकती है।

यहाँ बताया गया है कि आपका कोड कैसा दिखेगा यदि सुझाए गए अनुसार बदल दिया जाए:

beforecreate: function (node, targetNode, type, to) {
    jQuery.ajax({
        url: 'http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value),
        success: function (result) {
            if (result.isOk == false) alert(result.message);
        },
        async: false
    });
}

97
वास्तव में, सिंक्रोनस कॉल के लिए get (), post (), load () का उपयोग करना असंभव है। केवल अजाक्स () में "एसिंक्स" पैरामीटर है, जिसे "गलत" पर सेट किया जा सकता है।
SLA80

39
@ SLA80 नहींं। चूँकि jQuery 1.1: stackoverflow.com/questions/6849686/…
StuperUser

16
@qualidafial मेरी टिप्पणी SLA80 की गलत टिप्पणी के उद्देश्य से है; सिंक्रोनस कॉल के लिए get (), post (), load () का उपयोग करना संभव है।
18

9
async झूठी अब jQuery> = 1.8 के लिए समर्थित नहीं है। Api.jquery.com/jQuery.ajax का संदर्भ लें
ken

22
@ken async: falseअभी भी jQuery> = 1.8 में समर्थित है। async: falseJqXHR ( $.Deferred) के साथ उपयोग करने की क्षमता को हटा दिया गया था। दूसरे शब्दों में, किसी को विरासत विधियों के बजाय, नई सफलता / त्रुटि / पूर्ण कॉलबैक विकल्पों का उपयोग करना चाहिए, जैसे jqXHR.done(),।
बेन जॉनसन

255

आप कॉल करके jQuery के Ajax सेटअप को सिंक्रोनस मोड में रख सकते हैं

jQuery.ajaxSetup({async:false});

और फिर अपने अजाक्स कॉल का उपयोग कर प्रदर्शन करें jQuery.get( ... );

तो बस इसे एक बार फिर से चालू करें

jQuery.ajaxSetup({async:true});

मुझे लगता है कि यह @Adam द्वारा सुझाए गए समान काम करता है, लेकिन यह किसी ऐसे व्यक्ति के लिए मददगार हो सकता है जो अपने jQuery.get()या jQuery.post()अधिक विस्तृत jQuery.ajax()वाक्यविन्यास को फिर से कॉन्फ़िगर करना चाहता है ।


56
यह वास्तव में बुरा विचार है, आप इसे वैश्विक स्तर पर क्यों स्थापित करेंगे? और फिर बाद में इसे परेशान करने के लिए मजबूर किया जाए?
जुआन मेंडेस

11
कम से कम, यह सबसे अच्छा बुरा विचार है। कहने के बजाय: "यहाँ कोई रास्ता नहीं है $.ajax()"। ;)
रज़ासर

136

उत्कृष्ट समाधान! मैंने देखा जब मैंने इसे लागू करने की कोशिश की थी कि अगर मैं सफलता खंड में एक मूल्य लौटाता हूं, तो यह अपरिभाषित के रूप में वापस आ गया। मुझे इसे एक चर में संग्रहीत करना था और उस चर को वापस करना था। यह वह विधि है जिसके साथ मैं आया था:

function getWhatever() {
  // strUrl is whatever URL you need to call
  var strUrl = "", strReturn = "";

  jQuery.ajax({
    url: strUrl,
    success: function(html) {
      strReturn = html;
    },
    async:false
  });

  return strReturn;
}

16
ऐसा इसलिए है क्योंकि आप कॉलबैक से एक मूल्य वापस कर रहे थे, बाहर नहीं getWhatever। इस प्रकार आप लौटे कुछ भी नहीं यानी undefinedअपने से getWhatever
ऑर्बिट

6
यह बिल्कुल गलत है। आप यह सुनिश्चित नहीं कर सकते कि 'strReturn' को वापस करते समय एक अतुल्यकालिक कॉल समाप्त हो गई है।
थॉमस फ्रिट्ज

61
यह एक सिंक्रोनस कॉल (async: false) है।
जेम्स Indy

85

ये सभी उत्तर इस बिंदु को याद करते हैं कि एसिंक्स के साथ एक अजाक्स कॉल करना: अजाक्स अनुरोध पूरा होने तक ब्राउज़र को लटका देगा। फ्लो कंट्रोल लाइब्रेरी का उपयोग करने से ब्राउज़र को लटकाए बिना इस समस्या का समाधान हो जाएगा। यहाँ Frame.js के साथ एक उदाहरण दिया गया है :

beforecreate: function(node,targetNode,type,to) {

    Frame(function(next)){

        jQuery.get('http://example.com/catalog/create/', next);
    });

    Frame(function(next, response)){

        alert(response);
        next();
    });

    Frame.init();
}

4
सिंक्रोनस कॉल तब आसान होती है जब आप REST बैक-एंड के लिए क्विक टेस्ट हार्नेस को एक साथ रखना चाहते हैं और कमबैक नरक से अधिक सरलता पसंद करेंगे।
डिस्टॉर्टम

50
function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


//example use
var msg=getURL("message.php");
alert(msg);

10
ध्यान दें कि, आपको यह मिल सकता है: 'अंत उपयोगकर्ता के अनुभव के लिए हानिकारक प्रभावों के कारण मुख्य थ्रेड पर सिंक्रोनस XMLHttpRequest को हटा दिया गया है।'
हरि

5
@ हरि मुख्य सूत्र का उपयोग किए बिना jQuery का उपयोग कर एक तुल्यकालिक अजाक्स कॉल करने का तरीका क्या है?
जोस नोबेल

7
मैं यह नहीं देखता कि इस उत्तर में कुछ भी है, यह केवल स्वीकृत उत्तर है जिसे किसी फ़ंक्शन में लपेटा गया है और चार साल बाद उत्तर दिया गया है। लोगों को C + P की सलाह देना बुरी बात है, क्योंकि फ़ंक्शन यह संकेत नहीं देता है कि वह क्या करता है। "तो getURLबनाम get? कोई मेरे ब्राउज़र को क्यों लटकाता है?" आदि
moopet

27

नोट: आपको async: falseइस चेतावनी संदेशों के कारण उपयोग नहीं करना चाहिए :

गेको 30.0 (फ़ायरफ़ॉक्स 30.0 / थंडरबर्ड 30.0 / सीमॉन्की 2.27) से शुरू होकर, उपयोगकर्ता अनुभव के नकारात्मक प्रभावों के कारण मुख्य धागे पर तुल्यकालिक अनुरोधों को हटा दिया गया है।

कंसोल में भी क्रोम इसके बारे में चेतावनी देता है:

मुख्य थ्रेड पर सिंक्रोनस XMLHttpRequest अंत उपयोगकर्ता के अनुभव के लिए हानिकारक प्रभावों के कारण हटा दिया गया है। अधिक मदद के लिए, https://xhr.spec.whatwg.org/ देखें

यह आपके पेज को तोड़ सकता है यदि आप ऐसा कुछ कर रहे हैं क्योंकि यह किसी भी दिन काम करना बंद कर सकता है।

यदि आप इसे एक तरह से करना चाहते हैं जो अभी भी महसूस करता है कि यह तुल्यकालिक है, लेकिन फिर भी ब्लॉक नहीं होता है तो आपको एसिंक्स / वेट का उपयोग करना चाहिए और शायद कुछ एजाक्स भी है जो नए फ़ेच एपीआई जैसे वादों पर आधारित है

async function foo() {
  var res = await fetch(url)
  console.log(res.ok)
  var json = await res.json()
  console.log(json)
}

जब पृष्ठ को उपयोगकर्ता द्वारा नेविगेट किया जा रहा हो या बंद किया जा रहा हो, तो संपादित करें X क्रोम पेज बर्खास्तगी में सिंक XHR को हटाने पर काम कर रहा है। इसमें पहले से लोड, अनलोड, पेजहाइड और विजुअलचेंज शामिल हैं।

यदि यह आपका उपयोग मामला है, तो आप इसके बजाय navigator.sendBeacon पर एक नज़र रखना चाहते हो सकता है

पृष्ठ के लिए यह संभव है कि HTTP हेडर या iframe की अनुमति विशेषता के साथ सिंक रीक को अक्षम करें


ध्यान दें कि आपको किसी भी अतुल्यकालिक त्रुटियों को पकड़ने के लिए अपने await fetch(url)कॉल को try... catchब्लॉक में लपेटना चाहिए ।
इनोस्टिया

4
फ़ंक्शन फू को asyncशुरुआत में केवल शब्द का उपयोग करके एक वादा में बदल दिया गया है , इसलिए आप foo().catch(...)इसे पकड़ने के लिए भी कर सकते हैं
अंतहीन

Chrome ने पहले ही async ajax को पेज के अंदर अस्वीकृत कर दिया था, beforeunloadलेकिन फिर नकारात्मक प्रतिक्रिया Bugs.chromium.org/p/chromium/issues/detail?id=952452
एलेक्स

26

ध्यान रखें कि यदि आप क्रॉस-डोमेन अजाक्स कॉल कर रहे हैं ( JSONP का उपयोग करके ) - तो आप इसे सिंक्रोनाइज़ नहीं कर सकते , asyncध्वज को jQuery द्वारा अनदेखा किया जाएगा।

$.ajax({
    url: "testserver.php",
    dataType: 'jsonp', // jsonp
    async: false //IGNORED!!
});

JSONP- कॉल के लिए आप उपयोग कर सकते हैं:

  1. अपने स्वयं के डोमेन के लिए अजाक्स-कॉल - और क्रॉस-डोमेन कॉल सर्वर-साइड करें
  2. एसिंक्रोनस रूप से काम करने के लिए अपना कोड बदलें
  3. फ़्रेम "जेएस" (इस उत्तर ) की तरह "फ़ंक्शन सिक्वेंसर" लाइब्रेरी का उपयोग करें
  4. निष्पादन को अवरुद्ध करने के बजाय UI को अवरुद्ध करें (यह उत्तर ) (मेरा पसंदीदा तरीका)

12

के साथ async: falseआप अपने आप को एक अवरुद्ध ब्राउज़र मिलता है। एक गैर अवरुद्ध तुल्यकालिक समाधान के लिए आप निम्नलिखित का उपयोग कर सकते हैं:

ES6 / ECMAScript2015

ES6 के साथ आप एक जनरेटर और सह पुस्तकालय का उपयोग कर सकते हैं :

beforecreate: function (node, targetNode, type, to) {
    co(function*(){  
        let result = yield jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
        //Just use the result here
    });
}

ES7

ES7 के साथ आप सिर्फ एसाइक वेट का उपयोग कर सकते हैं:

beforecreate: function (node, targetNode, type, to) {
    (async function(){
        let result = await jQuery.get('http://example.com/catalog/create/' + targetNode.id + '?name=' + encode(to.inp[0].value));
        //Just use the result here
    })(); 
}

3
ध्यान दें कि आप बस async functionbeforecreate के पास जा सकते हैं beforecreate: async function(....और स्व-आह्वान किए गए async फ़ंक्शन को हटा सकते हैं
डैनियल क्रॉम

12

मैंने Carcione द्वारा दिए गए उत्तर का उपयोग किया और इसे JSON का उपयोग करने के लिए संशोधित किया।

 function getUrlJsonSync(url){

    var jqxhr = $.ajax({
        type: "GET",
        url: url,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}    

function testGetUrlJsonSync()
{
    var reply = getUrlJsonSync("myurl");

    if (reply.valid == 'OK')
    {
        console.dir(reply.data);
    }
    else
    {
        alert('not valid');
    }    
}

मैं जोड़ा डेटाप्रकार की 'JSON' और बदल .responseText को responseJSON

मैंने लौटी हुई वस्तु के स्टेटसटैक्स प्रॉपर्टी का उपयोग करके स्थिति को पुनः प्राप्त किया । ध्यान दें, यह अजाक्स प्रतिक्रिया की स्थिति है, यह नहीं कि क्या JSON मान्य है।

बैक-एंड को सही (अच्छी तरह से गठित) JSON में प्रतिक्रिया वापस करनी है, अन्यथा लौटी हुई वस्तु अपरिभाषित होगी।

मूल प्रश्न का उत्तर देते समय विचार करने के दो पहलू हैं। एक Ajax को सिंक्रोनाइज़ करने के लिए कह रहा है ( async: false को सेट करके ) और दूसरा कॉलबैक फ़ंक्शन के बजाय कॉलिंग फ़ंक्शन के रिटर्न स्टेटमेंट के माध्यम से प्रतिक्रिया लौटा रहा है।

मैंने इसे POST के साथ भी आजमाया और इसने काम किया।

मैंने GET को POST में बदल दिया और डेटा को जोड़ा : पोस्टडेटा

function postUrlJsonSync(url, postdata){

    var jqxhr = $.ajax({
        type: "POST",
        url: url,
        data: postdata,
        dataType: 'json',
        cache: false,
        async: false
    });

    // 'async' has to be 'false' for this to work
    var response = {valid: jqxhr.statusText,  data: jqxhr.responseJSON};

    return response;
}

ध्यान दें कि उपरोक्त कोड केवल इस मामले में जहां में काम करता है async है झूठी । यदि आप async सेट करने के लिए थे : सच है लौटी हुई वस्तु jqxhr उस समय मान्य नहीं होगी, जब AJAX कॉल लौटाएगी , केवल बाद में जब एसिंक्रोनस कॉल समाप्त हो गई हो, लेकिन प्रतिक्रिया चर को सेट करने में बहुत देर हो चुकी हो ।


7

यह उदाहरण है:

$.ajax({
  url: "test.html",
  async: false
}).done(function(data) {
   // Todo something..
}).fail(function(xhr)  {
   // Todo something..
});

1
async falseवादा-आधारित समाधान के साथ उपयोग करने का क्या मतलब है । यह केवल ब्राउज़र को बिना किसी लाभ के लॉक करता है।
कोडिंग हुई

2
@Gone कोडिंग ऐसी परिस्थितियां हैं, जहां सटीक अनुक्रम में कोड निष्पादित करना चाहते हैं, उस स्थिति में हम async false का उपयोग कर सकते हैं
निक्की

1
@ निक्की: यह बिल्कुल उन्हें क्रमिक रूप से चलाने का तरीका नहीं है। Async वादों का उपयोग करें (जो ajaxपहले से ही कॉल करता है ) और .then()या done()(जैसा कि यह पहले से ही दिखाता है)। ब्राउज़र को लॉक करना एक बहुत ही खराब उपयोगकर्ता अनुभव है। जैसा कि मैंने कहा कि async: falseइस उदाहरण में समय की पूरी बर्बादी है।
कोडिंग किया

4

सबसे पहले हमें समझना चाहिए कि जब हम $ .ajax का उपयोग करते हैं और जब हम $ .get / $ का उपयोग करते हैं। पोस्ट

जब हमें ajax अनुरोध पर निम्न स्तर नियंत्रण की आवश्यकता होती है, जैसे अनुरोध हेडर सेटिंग्स, कैशिंग सेटिंग्स, सिंक्रोनस सेटिंग्स आदि तो हमें $ .ajax के लिए जाना चाहिए।

$ .get / $। पोस्ट: जब हमें ajax अनुरोध पर निम्न स्तर के नियंत्रण की आवश्यकता नहीं होती है। केवल सर्वर को डेटा प्राप्त / पोस्ट करना सरल होता है। यह आशुलिपि है

$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

और इसलिए हम $ .get / $ पोस्ट के साथ अन्य सुविधाओं (सिंक, कैश आदि) का उपयोग नहीं कर सकते हैं।

अजाक्स अनुरोध पर निम्न स्तर नियंत्रण (सिंक, कैश आदि) के लिए, हमें $ .ajax के लिए जाना चाहिए

 $.ajax({
     type: 'GET',
      url: url,
      data: data,
      success: success,
      dataType: dataType,
      async:false
    });

2

यह jQuery के साथ ASYNC अनुरोधों के लिए मेरा सरल कार्यान्वयन है। मुझे उम्मीद है कि यह किसी की मदद करेगा।

var queueUrlsForRemove = [
    'http://dev-myurl.com/image/1', 
    'http://dev-myurl.com/image/2',
    'http://dev-myurl.com/image/3',
];

var queueImagesDelete = function(){

    deleteImage( queueUrlsForRemove.splice(0,1), function(){
        if (queueUrlsForRemove.length > 0) {
            queueImagesDelete();
        }
    });

}

var deleteImage = function(url, callback) {
    $.ajax({
        url: url,
        method: 'DELETE'
    }).done(function(response){
        typeof(callback) == 'function' ? callback(response) : null;
    });
}

queueImagesDelete();

2

क्योंकि XMLHttpReponseसिंक्रोनस ऑपरेशन को पदावनत किया जाता है, मैं निम्नलिखित समाधान के साथ आया हूं जो लपेटता है XMLHttpRequest। यह प्रकृति में असावधान होते हुए भी AJAX प्रश्नों का आदेश देता है, जो CSRF टोकन के एकल उपयोग के लिए बहुत उपयोगी है।

यह पारदर्शी भी है इसलिए पुस्तकालय जैसे कि jQuery मूल रूप से काम करेगा।

/* wrap XMLHttpRequest for synchronous operation */
var XHRQueue = [];
var _XMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function()
{
  var xhr   = new _XMLHttpRequest();
  var _send = xhr.send;

  xhr.send = function()
  {
    /* queue the request, and if it's the first, process it */
    XHRQueue.push([this, arguments]);
    if (XHRQueue.length == 1)
      this.processQueue();
  };

  xhr.processQueue = function()
  {
    var call = XHRQueue[0];
    var xhr  = call[0];
    var args = call[1];

    /* you could also set a CSRF token header here */

    /* send the request */
    _send.apply(xhr, args);
  };

  xhr.addEventListener('load', function(e)
  {
    /* you could also retrieve a CSRF token header here */

    /* remove the completed request and if there is more, trigger the next */
    XHRQueue.shift();
    if (XHRQueue.length)
      this.processQueue();
  });

  return xhr;
};

-1

चूँकि मूल प्रश्न के बारे में था jQuery.get, यह यहाँ ध्यान देने योग्य है कि (जैसा कि यहाँ बताया गया है ) कोई भी उपयोग कर सकताasync: false है, $.get()लेकिन आदर्श रूप से इससे बच सकते हैं क्योंकि अतुल्यकालिक XMLHTTPRequestपदावनत है (और ब्राउज़र चेतावनी दे सकता है):

$.get({
  url: url,// mandatory
  data: data,
  success: success,
  dataType: dataType,
  async:false // to make it synchronous
});

1
यह क्यों घटाया गया है?
alias51

-2

asyn:falseइसे समकालिक बनाने के लिए अजाक्स अनुरोध में सेट करें ।

यहाँ कोड नमूना है:

 $.ajax({
    url: 'some_url',
    type: "GET",
    async: false,
    cache: false,
    dataType: "JSON",
    data: { 
      "p1": v1, 
      "p2": v2
    },
    success: function(result) {
    }  
  }
});

यह स्क्रीन को अनुत्तरदायी बना सकता है।

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