سؤال

أنا استخدام jQuery. وأنا لا أريد مكالمات AJAX الموازية في طلبي، يجب أن تنتظر كل مكالمة السابقة قبل البدء. كيفية تنفيذها؟ هناك أي مساعد؟

تحديث إذا كان هناك أي إصدار متزامن من XMLHTPREQUEST أو JQUERY.POST أود أن أعرف. لكن متسلسل! = متزامن، وأود أن حل غير متزامن ومتسلم.

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

المحلول

هناك طريقة أفضل بكثير للقيام بذلك من استخدام مكالمات AJAX المتزامنة. JQuery Ajax إرجاع مؤجل حتى تتمكن من استخدام تسخين الأنبوب للتأكد من أن كل مكالمة AJAX تنتهي قبل التشغيل التالي. إليك مثالا للعمل مثال أكثر عمقا العب مع jsfiddle.

// How to force async functions to execute sequentially 
// by using deferred pipe chaining.

// The master deferred.
var dfd = $.Deferred(),  // Master deferred
    dfdNext = dfd; // Next deferred in the chain
    x = 0, // Loop index
    values = [], 

    // Simulates $.ajax, but with predictable behaviour.
    // You only need to understand that higher 'value' param 
    // will finish earlier.
    simulateAjax = function (value) {
        var dfdAjax = $.Deferred();

        setTimeout(
            function () {
                dfdAjax.resolve(value);
            },
            1000 - (value * 100)
        );

        return dfdAjax.promise();
    },

    // This would be a user function that makes an ajax request.
    // In normal code you'd be using $.ajax instead of simulateAjax.
    requestAjax = function (value) {
        return simulateAjax(value);
    };

// Start the pipe chain.  You should be able to do 
// this anywhere in the program, even
// at the end,and it should still give the same results.
dfd.resolve();

// Deferred pipe chaining.
// What you want to note here is that an new 
// ajax call will not start until the previous
// ajax call is completely finished.
for (x = 1; x <= 4; x++) {

    values.push(x);

    dfdNext = dfdNext.pipe(function () {
        var value = values.shift();
        return requestAjax(value).
            done(function(response) {
                // Process the response here.

            });

    });

}

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

نصائح أخرى

لديك خياران أستطيع التفكير فيه. واحد هو السلسلة لهم من خلال عمليات الاسترجاعات. والآخر هو جعل المكالمات متزامنة بدلا من Async.

هل هناك سبب تريدهم متتابعين؟ هذا سوف تبطئ الأمور.

لجعل المكالمة متزامنة، ستقوم بتعيين خيار ASYNC في استدعاء AJAX إلى False. انظر الوثائق في http://docs.jquery.com/ajax/jquery.ajaxhoyptions. (انقر فوق "خيارات Tab" لرؤيتها).

يمكنك إعطاء جافا سكريبت السرد http://www.neilmix.com/narriatesjs/doc/

أنا لم أستخدمها بنفسي. إذا كنت أرغب في القيام بذلك، أود أن أقوم بإعداد نوع من التجريد لسلسلة الإجراءات غير المتزامنة. كما قال آخرون، فإن النسخة المتزامنين من كائنات كائن AJAX الأحداث من معالجتها أثناء انتظار الرد. هذا يؤدي هذا المتصفح إلى أن يبدو وكأنه مجمده حتى يستلم الرد.

أفضل طريقة يمكنك القيام بذلك هي عن طريق استقلاع استشعار كما قال نوسريدنا. لن أوصي باستخدام XMLHTTPRECEST متزامن لأنها قفل التطبيق بأكمله.

لا يوجد الكثير من المساعد حتى الآن كما أعرف، ولكن يمكنك القيام بشيء يشبه رد الاتصال FIFO.

انظروا الى هذا: http://docs.jquery.com/ajax/jquery.ajax. (انقر فوق علامة التبويب "خيارات").

ولكن تذكر أن مكالمة متزامنة ستقوم بتجميد الصفحة حتى يتم استلام الاستجابة، لذلك لا يمكن استخدامها في موقع الإنتاج، لأن المستخدمين سوف يتجولون إذا كان عليهم أي سبب من أي سبب يجب عليهم الانتظار لمدة 30 ثانية مع متصفحهم المجمدة.

تحرير: موافق، مع التحديث الخاص بك، إنه أمر أكثر وضوحا ما تريد تحقيقه؛)

لذلك، قد يبدو رمزك مثل هذا:

    $.getJSON("http://example.com/jsoncall", function(data) {
        process(data);
        $.getJSON("http://example.com/jsoncall2", function (data) {
            processAgain(data);
            $.getJSON("http://example.com/anotherjsoncall", function(data) {
                processAgainAndAgain(data);
            });
        });
    });

وبهذه الطريقة، سيتم إصدار الدعوة الثانية فقط عند استلام الاستجابة للمكالمة الأولى ومعالجتها، وسيتم إصدار الدعوة الثالثة فقط عند استلام الاستجابة للمكالمات الثانية ومعالجتها. هذا الرمز هو ل GetJson ولكن يمكن تكييفها مع $ .jax.

تعيين async. خيار false، على سبيل المثال،

$.ajax({ async: false /*, your_other_ajax_options_here */ });

مرجع: ajax / jquery.ajax.

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

(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. طلبات 3 ملفات JSON مع JQuery Ajax يدعو
  2. عملية بالتسلسل (وليس بالتوازي) مع انتظار
  3. يعمل في Chrome / Firefox / Edge (اعتبارا من 1/30/2018)

أكثر في MDN.

يمكنك استخدام الوعد لجعل AJAX يستدعي التسلسل. باستخدام طريقة تشغيل مجموعة وعد البوب، ستكون مكالمات AJAX المتسلسلة أسهل كثيرا.

var promises = [Promise.resolve()];

function methodThatReturnsAPromise(id) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/'+id,
      dataType:'json',
      success: function(data)
      {
        console.log("Ajax Request Id"+id);
        console.log(data);
        resolve();
      }
    });
  });
} 

function pushPromise(id)
{
  promises.push(promises.pop().then(function(){
    return methodThatReturnsAPromise(id)}));
}


pushPromise(1);
pushPromise(3);
pushPromise(2);

ماذا عن استخدام أحداث node.js؟

var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var $ = require('jquery');

var doSomething = function (responseData) {
  var nextRequestData = {};
  // do something with responseData
  return nextRequestData;
};

// ajax requests
var request1 = $.ajax;
var request2 = $.ajax;
var requests = [request1, request2];

eventEmitter.on('next', function (i, requestData) {
  requests[i](requestData).then(
    function (responseData) {
      console.log(i, 'request completed');
      if (i+1 < requests.length) {
        var nextRequestData = doSomething(responseData);
        eventEmitter.emit('next', i+1, nextRequestData);
      }
      else {
        console.log('completed all requests');
      }
    },
    function () {
      console.log(i, 'request failed');
    }
  );
});

var data = {
  //data to send with request 1
};
eventEmitter.emit('next', 0, data);

متسلسل! = متزامن، وأود أن الحل غير المتزامن والتسلمني

يعني التنفيذ المتزامن بشكل عام "استخدام نفس الساعة"، بينما يعني التنفيذ المتسلسل "التالي بالترتيب أو التسلسل".

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top