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

StackOverflow https://stackoverflow.com/questions/133310

سؤال

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

لقد وأضاف اياكس في هذه الوظيفة باستخدام مسج:

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 في الأم-وظيفة وليس في الاستدعاء.هل هناك طريقة لأداء متزامن طلب اياكس باستخدام مسج أو أي دولة أخرى في متصفح API ؟

هل كانت مفيدة؟

المحلول

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

هنا ما التعليمات البرمجية الخاصة بك ستبدو إذا تغيرت كما اقترح:

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

نصائح أخرى

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

jQuery.ajaxSetup({async:false});

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

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

jQuery.ajaxSetup({async:true});

أعتقد أنه يعمل نفس الشيء كما اقترح @آدم ، ولكن قد يكون من المفيد أن شخص لا ترغب في إعادة تكوين بهم 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;
}

كل هذه الإجابات تفوت هذه النقطة أن تفعل اياكس الاتصال مع المتزامن:كاذبة سوف يسبب المتصفح إلى تعليق حتى طلب اياكس يكمل.باستخدام التحكم في التدفق المكتبة سوف تحل هذه المشكلة دون شنقا حتى المتصفح.هنا مثال مع 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();
}
function getURL(url){
    return $.ajax({
        type: "GET",
        url: url,
        cache: false,
        async: false
    }).responseText;
}


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

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

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

بالنسبة JSONP-المكالمات يمكنك استخدام:

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

ملاحظة:يجب عدم استخدام async: false بسبب هذا التحذير الرسائل:

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

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

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

هذا يمكن أن يكسر الصفحة الخاصة بك إذا كنت تفعل شيئا من هذا القبيل لأنها يمكن أن تتوقف عن العمل في أي يوم.

إذا كنت تريد أن تفعل ذلك بطريقة لا يزال يشعر كما لو كان متزامن ولكن لا يزال لا كتلة ثم يجب عليك استخدام المتزامن/ننتظر وربما أيضا بعض اياكس استنادا إلى وعود مثل الجديد جلب API

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

تحرير كروم يعمل على تنكر مزامنة XHR في الصفحة الفصل عندما تكون الصفحة التي أبحر بعيدا أو مغلقة من قبل المستخدم.وهذا ينطوي على beforeunload ، تفريغ ، pagehide و visibilitychange.

إذا كانت هذه هي الحالة استخدام فإنك قد ترغب في إلقاء نظرة على الملاح.sendBeacon بدلا من ذلك

ومن الممكن أيضا الصفحة إلى تعطيل المزامنة req إما مع رؤوس http أو iframe تسمح السمة

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

لقد استخدمت الإجابة التي قدمها Carcione و تعديله إلى استخدام سلمان.

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

أضفت نوع البيانات من 'سلمان' وغيرت .responseText إلى responseJSON.

أنا أيضا استرجاع حالة استخدام statusText خاصية الكائن عاد.علما أن هذه هي حالة استجابة اياكس, ليس ما إذا كان سلمان صالح.

الخلفية إعادة الاستجابة في الصحيح (بشكل جيد) سلمان, وإلا عاد الكائن غير معروف.

هناك نوعان من الجوانب في الاعتبار عند الإجابة على السؤال الأصلي.واحد يقول اياكس لأداء بشكل متزامن (عن طريق وضع المتزامن:كاذبة) والآخر هو العودة الاستجابة من خلال وظيفة الدعوة عودة البيان ، وليس إلى وظيفة رد الاتصال.

كما أنني حاولت ذلك مع وظيفة عمل.

لقد غيرت الحصول على وظيفة ، وأضاف البيانات:postdata

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

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

هذا هو على سبيل المثال:

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

أولا علينا أن نفهم عندما نستخدم $.اياكس وعندما نستخدم $.الحصول على/$.بعد

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

$.الحصول على/$.وظيفة:عندما لا تتطلب مستوى منخفض السيطرة على طلب اياكس.فقط الحصول بسيطة/آخر البيانات إلى الخادم.هو اختزال

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

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

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

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

هذا هو بلدي بسيطة التنفيذ المتزامن الطلبات مع مسج.آمل أن يكون هذا مساعدة أي شخص.

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

لأن XMLHttpReponse عملية متزامنة هو مستنكر لقد جاء مع الحل التالي الذي يلتف XMLHttpRequest.يسمح هذا أمر اياكس الاستعلامات في حين لا يزال يجري asycnronous في الطبيعة ، وهي مفيدة جدا للاستخدام مرة واحدة CSRF الرموز.

كما أنها شفافة حتى المكتبات مثل مسج سوف تعمل بسلاسة.

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

هذا هو بلدي "الموضوع"مساحة:

var Thread = {
    sleep: function(ms) {
        var start = Date.now();

        while (true) {
            var clock = (Date.now() - start);
            if (clock >= ms) break;
        }

    }
};

و هذا هو كيف لي أن أسميها:

var d1 = new Date();
console.log('start ' + d1.toLocaleTimeString());
Thread.sleep(10000);
var d2 = new Date();
console.log('end ' + d2.toLocaleTimeString());

وإذا كنت تبحث في وحدة التحكم نحصل على النتيجة التالية:

start 1:41:21 PM
end 1:41:31 PM
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top