javascript ajax - كيف يمكنني الحصول على jQuery لأداء متزامن ، بدلا من الطلب غير المتزامن ، أجاكس؟




documentation load (12)

تفوت كل هذه الإجابات النقطة التي يؤدي بها إجراء مكالمة أجاكس باستخدام async: false إلى تعليق المتصفح حتى يكتمل طلب Ajax. سيؤدي استخدام مكتبة التحكم في التدفق إلى حل هذه المشكلة بدون تعليق المتصفح. هذا مثال على ذلك مع 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();
}

لدي أداة جافا سكريبت التي توفر نقاط تمديد قياسية. واحد منهم هو وظيفة beforecreate . يجب أن يقوم بإرجاع false لمنع إنشاء عنصر.

لقد قمت بإضافة مكالمة Ajax إلى هذه الوظيفة باستخدام 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 في وظيفة الأم ، وليس في معاودة الاتصال. هل هناك طريقة لتنفيذ طلب Ajax متزامن باستخدام jQuery أو أي واجهة برمجة تطبيقات أخرى؟


ملاحظة: يجب ألا تستخدم التزامن بسبب هذا:

بدءًا من Gecko 30.0 (فايرفوكس 30.0 / Thunderbird 30.0 / SeaMonkey 2.27) ، تم إيقاف الطلبات المتزامنة على الخيط الرئيسي نظرًا للتأثيرات السلبية على تجربة المستخدم.

يحذر Chrome حتى من ذلك في وحدة التحكم:

تم إهمال XML متزامن XMLHttpRequest على مؤشر الترابط الرئيسي بسبب آثاره الضارة إلى تجربة المستخدم النهائي. لمزيد من المساعدة ، تحقق من https://xhr.spec.whatwg.org/ .

قد يؤدي ذلك إلى تعطيل صفحتك إذا كنت تفعل شيئًا كهذا نظرًا لأنها قد تتوقف عن العمل في أي يوم.

إذا كنت تريد إجراء ذلك بطريقة لا تزال تشبه إذا كانت متزامنة ولكن لا تزال غير محظورة ، فيجب عليك استخدام async / await وربما أيضًا بعض الإجابات التي تستند إلى الوعود مثل Fetch API الجديد

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

من وثائق jQuery : تقوم بتحديد الخيار غير المتزامن ليكون false للحصول على طلب 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
    });
}

هذا هو المثال:

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

باستخدام برنامج 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 يمكنك فقط استخدام asyc في انتظار:

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

هذا هو تنفيذ بسيط لطلبات ASYNC مع jQuery. آمل أن يساعد هذا أي شخص.

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

ضع في اعتبارك أنه في حالة قيامك بإجراء مكالمة عبر Ajax (عبر استخدام JSONP ) - لا يمكنك القيام بذلك بشكل متزامن ، سيتم تجاهل علامة async من خلال jQuery.

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

بالنسبة إلى مكالمات JSONP ، يمكنك استخدام:

  1. اياكس-الدعوة إلى المجال الخاص بك - والقيام من جانب الخادم استدعاء عبر النطاقات
  2. تغيير التعليمات البرمجية للعمل بشكل غير متزامن
  3. استخدام مكتبة "وظيفة التسلسل" مثل Frame.js (هذا answer )
  4. حظر واجهة المستخدم بدلاً من حظر التنفيذ (هذه answer ) (الطريقة المفضلة)

أولاً يجب أن نفهم عندما نستخدم $ .ajax وعندما نستخدم $ .get / $

عندما نطلب التحكم بمستوى منخفض عبر طلب ajax مثل إعدادات رأس الطلب ، وإعدادات التخزين المؤقت ، والإعدادات المتزامنة وما إلى ذلك ، يجب أن نذهب إلى $ .ajax.

$ .get / $. post: عندما لا نطلب التحكم بمستوى منخفض عبر طلب ajax. ببساطة بسيطة تحصل / بعد البيانات إلى الخادم. ومن اختزال

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

وبالتالي لا يمكننا استخدام ميزات أخرى (المزامنة أو ذاكرة التخزين المؤقت إلخ) مع مشاركة $ .get / $.

ومن ثم ، بالنسبة للتحكم في مستوى منخفض (المزامنة ، ذاكرة التخزين المؤقت ، إلخ.) عبر طلب ajax ، يجب أن نذهب إلى $ .ajax

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

يمكنك وضع إعداد Ajax jQuery في الوضع المتزامن عن طريق الاتصال

jQuery.ajaxSetup({async:false});

ثم قم بإجراء مكالمات Ajax باستخدام jQuery.get( ... );

ثم أعد تشغيلها مرة أخرى

jQuery.ajaxSetup({async:true});

أعتقد أنه يعمل نفس الشيء كما هو مقترح بواسطةAdam ، ولكن قد يكون من المفيد لشخص يرغب في إعادة تكوين jQuery.get() أو jQuery.post() إلى صياغة jQuery.ajax() الأكثر تفصيلاً.


بسبب إهمال عملية متزامن 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;
};

حل ممتاز! لاحظت عندما حاولت تنفيذ ذلك ، إذا قمت بإرجاع قيمة في بند النجاح ، فعدت على أنها غير محددة. اضطررت إلى تخزينها في متغير وإرجاع هذا المتغير. هذه هي الطريقة التي توصلت إليها:

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





javascript jquery ajax asynchronous