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




ajax asynchronous (9)

मेरे पास एक जावास्क्रिप्ट विजेट है जो मानक विस्तार बिंदु प्रदान करता है। उनमें से एक पहले से 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 या किसी अन्य एपीआई का उपयोग कर एक सिंक्रनाइज़ अजाक्स अनुरोध करने का कोई तरीका है?


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();

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

jQuery.ajaxSetup({async:false});

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

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

jQuery.ajaxSetup({async:true});

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


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

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;
}

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

यह भी पारदर्शी है इसलिए 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;
};

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

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

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

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

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

यदि आप ऐसा करना चाहते हैं जो अभी भी ऐसा लगता है कि यह सिंक्रोनस है लेकिन फिर भी ब्लॉक नहीं करता है तो आपको एसिंक / प्रतीक्षा का उपयोग करना चाहिए और शायद कुछ एजेक्स भी जो कि नए Fetch API जैसे वादों पर आधारित है

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

मैंने कार्सीओन द्वारा दिए गए उत्तर का उपयोग किया और 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 को बदल दिया।

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

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

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

मैंने पोस्ट के साथ भी कोशिश की और यह काम किया।

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

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 कॉल रिटर्न के समय मान्य नहीं होगा, केवल बाद में जब एसिंक्रोनस कॉल समाप्त हो गया है, लेकिन प्रतिक्रिया चर सेट करने में बहुत देर हो चुकी है।


JQuery दस्तावेज़ से : आप एक सिंक्रोनस अजाक्स अनुरोध प्राप्त करने के लिए असीमित होने के लिए असीमित विकल्प निर्दिष्ट करते हैं। फिर आपकी कॉलबैक आपकी मां की कार्यवाही से पहले कुछ डेटा सेट कर सकती है।

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

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
    });
}

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

ES6 / ECMAScript2015

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

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

ईएस 7 के साथ आप एएससीसी का इंतजार कर सकते हैं:

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
    })(); 
}

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


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




asynchronous