কিভাবে jQuery AJAX অনুরোধ বাতিল / বাতিল?


244

আমার একটি এজেএক্স অনুরোধ রয়েছে যা প্রতি 5 সেকেন্ডে তৈরি করা হবে। তবে পূর্ববর্তী অনুরোধটি যদি শেষ না হয় তবে আমি এই অনুরোধটি বাতিল করে একটি নতুন অনুরোধ জানাতে চাইছি এজ্যাক্সের অনুরোধের আগে সমস্যা।

আমার কোডটি এরকম কিছু, এই সমস্যাটি কীভাবে সমাধান করবেন?

$(document).ready(
    var fn = function(){
        $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);


5
আপনার প্রশ্নে অনুরোধটি প্রতি 5 সেকেন্ডে হওয়া উচিত, তবে কোডটি 500 এমএস = 0.5 এস ব্যবহার করে।
জিওন

উত্তর:


355

Jquery আজাক্স পদ্ধতিটি একটি এক্সএমএলএইচটিপিআরকোয়েস্ট অবজেক্ট দেয়। আপনি অনুরোধটি বাতিল করতে এই অবজেক্টটি ব্যবহার করতে পারেন।

এক্সএমএলএইচটিপিআরকোয়েস্টের একটি গর্ভপাত পদ্ধতি রয়েছে, যা অনুরোধটি বাতিল করে দেয়, তবে যদি অনুরোধটি ইতিমধ্যে সার্ভারে প্রেরণ করা হয়ে থাকে তবে সার্ভারটি অনুরোধটি প্রক্রিয়া করবে এমনকি আমরা অনুরোধ বাতিল করলেও ক্লায়েন্ট প্রতিক্রিয়াটির জন্য অপেক্ষা / অপেক্ষা করবে না।

এক্সএইচআর অবজেক্টে একটি রেডিস্টেটও রয়েছে যা অনুরোধের রাজ্য (UNSENT-0, ওপেন -1, HEADERS_RECEIVED-2, লোডিং -3 এবং সম্পন্ন 4) ধারণ করে। আমরা পূর্বের অনুরোধটি সম্পন্ন হয়েছে কিনা তা পরীক্ষা করতে এটি ব্যবহার করতে পারি can

$(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
);

60
@ ক্রোমেকেন্স পার্থক্যটি readystateউপরে এবং readyStateনীচের সম্পত্তি , চরিত্রটি sjQuery 1.5 তে মূলধন করা হয়েছে
অরুণ পি জনি

আমি ভাবছিলাম যে যদি রেডিস্টেটটি "লোডিং -3" হয় এবং আমরা গর্ভপাত করি তবে কী হবে? ডেটা সার্ভারে প্রেরণ করা হয় এবং এটি প্রক্রিয়াজাত হয় বা হয় না। আমরা জানব না ...: এস
inf3rno

7
বিটিডব্লু, আমি মনে করি রেডিস্টেট চেকটি অপ্রয়োজনীয়, যেহেতু এটি পিছিয়ে গেছে এবং একবার সমাধান হয়ে গেলে বা প্রত্যাখ্যান হয়ে গেলে তা অন্যকে চালিত করে না। সুতরাং if (xhr) xhr.abort();ঠিক ঠিক কাজ করবে।
সিয়ানটিক

2
ডাব্লু 3 কখনই readystateএর ডকুমেন্টেশনে মূলধন ব্যবহার করে না । এটি সর্বদা বড় readyStateআকারের এবং jquery (1.5 এর আগে বা তার পরে) ডাব্লু 3 স্পেসিফিকেশনের সাথে সঠিকভাবে মেলে।
আরশসফট

@ArunPJohny, আপনি এই প্রশ্ন pls পারেন stackoverflow.com/questions/49801146/...
কৃষ্ণ Jonnalagadda

6

আপনি যখন কোনও সার্ভারের কাছে একটি অনুরোধ করবেন, তখন কোনও অগ্রগতিটি বাতিল হয় না তা পরীক্ষা করে দেখুন (বা সেই তথ্যটি আনা হচ্ছে)। যদি এটি ডেটা আনতে থাকে তবে পূর্বের অনুরোধটি বাতিল করুন এবং নতুনটি শুরু করুন।

var progress = null

function fn () {    
    if (progress) {
        progress.abort();
    }
    progress = $.ajax('ajax/progress.ftl', {
        success: function(data) {
            //do something
            progress = null;
        }
    });
}

5

আমি জানি এটি কিছুটা দেরিতে হতে পারে তবে আমি একই ধরণের সমস্যাগুলি অনুভব করি যেখানে অ্যাবੋਰਟ পদ্ধতিটি কল করা সত্যিই অনুরোধটি বাতিল করে দেয়নি। পরিবর্তে ব্রাউজারটি এখনও এমন কোনও প্রতিক্রিয়ার জন্য অপেক্ষা করছিল যা এটি কখনও ব্যবহার করে না। এই কোডটি এই সমস্যাটিকে সমাধান করেছে।

 try {
        xhr.onreadystatechange = null;
        xhr.abort();
} catch (e) {}

1

আপনার অনুরোধটি কেন বাতিল করা উচিত?

প্রতিটি অনুরোধ যদি পাঁচ সেকেন্ডের বেশি সময় নেয় তবে কী হবে?

অনুরোধটির সাথে প্যারামিটারটি পরিবর্তিত না হলে আপনার অনুরোধটি বাতিল করা উচিত নয়। যেমন: - অনুরোধটি বিজ্ঞপ্তি ডেটা পুনরুদ্ধারের জন্য। এই জাতীয় পরিস্থিতিতে, দুর্দান্ত অ্যাপ্রোচটি হ'ল পূর্ববর্তী অ্যাজাক্স অনুরোধটি শেষ করেই একটি নতুন অনুরোধ সেট করা।

$(document).ready(

    var fn = function(){

        $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            },

            complete: function(){setTimeout(fn, 500);}
        });
    };

     var interval = setTimeout(fn, 500);

);

5
এটি একটি খারাপ ধারণা। নতুন কল শুরু করার সময়, আপনি চান না যে পুরো ইভেন্টটি আগের কলটি থেকে সরিয়ে দেওয়া হোক। আপনি এই পদ্ধতির সাথে খুব অদ্ভুত ফলাফল পেতে পারেন।
ওয়েববারিগ

1

আপনি jquery-validate.js ব্যবহার করতে পারেন। নীচে jquery-validate.js এর কোড স্নিপেট।

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()

var pendingRequests = {},
    ajax;
// Use a prefilter if available (1.5+)
if ( $.ajaxPrefilter ) {
    $.ajaxPrefilter(function( settings, _, xhr ) {
        var port = settings.port;
        if ( settings.mode === "abort" ) {
            if ( pendingRequests[port] ) {
                pendingRequests[port].abort();
            }
            pendingRequests[port] = xhr;
        }
    });
} else {
    // Proxy ajax
    ajax = $.ajax;
    $.ajax = function( settings ) {
        var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
            port = ( "port" in settings ? settings : $.ajaxSettings ).port;
        if ( mode === "abort" ) {
            if ( pendingRequests[port] ) {
                pendingRequests[port].abort();
            }
            pendingRequests[port] = ajax.apply(this, arguments);
            return pendingRequests[port];
        }
        return ajax.apply(this, arguments);
    };
}

তাই আপনি শুধু শুধু প্যারামিটার সেট করতে হবে যে মোড থেকে বাতিল যখন আপনি AJAX অনুরোধ তৈরি করছেন।

তথ্যসূত্র: https://cdnjs.cloudflare.com/ajax/libs/jquery-uthorate/1.14.0/jquery.uthorate.js


0

jQuery: অনুপ্রেরণা হিসাবে এটি একটি সূচনা পয়েন্ট হিসাবে ব্যবহার করুন। আমি এটি এর মতো সমাধান করেছি: (এটি একটি নিখুঁত সমাধান নয়, এটি কেবল সর্বশেষ উদাহরণটি বাতিল করে এবং এটি ডাব্লুআইপি কোড)

var singleAjax = function singleAjax_constructor(url, params) {
    // remember last jQuery's get request
    if (this.lastInstance) {
        this.lastInstance.abort();  // triggers .always() and .fail()
        this.lastInstance = false;
    }

    // how to use Deferred : http://api.jquery.com/category/deferred-object/
    var $def = new $.Deferred();

    // pass the deferrer's request handlers into the get response handlers
    this.lastInstance = $.get(url, params)
        .fail($def.reject)         // triggers .always() and .fail()
        .success($def.resolve);    // triggers .always() and .done()

    // return the deferrer's "control object", the promise object
    return $def.promise();
}


// initiate first call
singleAjax('/ajax.php', {a: 1, b: 2})
    .always(function(a,b,c) {console && console.log(a,b,c);});

// second call kills first one
singleAjax('/ajax.php', {a: 1, b: 2})
    .always(function(a,b,c) {console && console.log(a,b,c);});
    // here you might use .always() .fail() .success() etc.

0

আপনার এপিআই কল করতে একটি ফাংশন তৈরি করুন। এই ফাংশনটির মধ্যে আমরা অনুরোধটিকে সংজ্ঞায়িত করি callApiRequest = $.get(...- যদিও এটি একটি ভেরিয়েবলের সংজ্ঞা হলেও অনুরোধটি তত্ক্ষণাত ডাকা হয় তবে এখন আমাদের অনুরোধটি একটি ভেরিয়েবল হিসাবে সংজ্ঞায়িত করা হয়েছে। অনুরোধটি আহ্বানের আগে, আমরা আমাদের ভেরিয়েবলটি সংজ্ঞায়িত করা হয়েছে typeof(callApiRequest) != 'undefined'কিনা তাও পরীক্ষা করে আছি এবং এটি মুলতুবি রয়েছে suggestCategoryRequest.state() == 'pending'কিনা - যদি উভয়ই সত্য হয়, আমরা .abort()অনুরোধটি যা সাফল্য কলব্যাকটি চালানো থেকে রোধ করবে।

// We need to wrap the call in a function
callApi = function () {

    //check if request is defined, and status pending
    if (typeof(callApiRequest) != 'undefined'
        && suggestCategoryRequest.state() == 'pending') {

        //abort request
        callApiRequest.abort()

    }

    //define and make request
    callApiRequest = $.get("https://example.com", function (data) {

        data = JSON.parse(data); //optional (for JSON data format)
        //success callback

    });
}

আপনার সার্ভার / এপিআই অনুরোধ বাতিল করতে সমর্থন করতে পারে না (যদি এপিআই ইতিমধ্যে কিছু কোড কার্যকর করে? তবে জাভাস্ক্রিপ্ট কলব্যাক চালু হবে না)। এটি দরকারী যখন উদাহরণস্বরূপ আপনি কোনও ব্যবহারকারীকে ইনপুট পরামর্শ সরবরাহ করছেন যেমন হ্যাশট্যাগস ইনপুট।

ত্রুটি কলব্যাকের সংজ্ঞা যুক্ত করে আপনি এই ফাংশনটি আরও বাড়িয়ে দিতে পারেন - যদি অনুরোধ বাতিল হয়ে যায় তবে কি হবে।

এই স্নিপেটের সাধারণ ব্যবহারের ক্ষেত্রে এটি একটি পাঠ্য ইনপুট হবে যা keypressইভেন্টে আগুন দেয় । আপনি একটি টাইমআউট ব্যবহার করতে পারেন, (কিছু) অনুরোধগুলি যা আপনাকে বাতিল করতে হবে তা পাঠানো রোধ করতে .abort()


-7

আপনার রেডিস্টেট 0 টি পরীক্ষা করা উচিত Because কারণ আপনি যখন xhr.abort ব্যবহার করেন () এই ফাংশনটি এই অবজেক্টে রেডিস্টেট সেট করে 0 এবং আপনার চেকটি সর্বদা সত্য হবে - রেডিস্টেট! = 4

$(document).ready(
    var xhr;

    var fn = function(){
        if(xhr && xhr.readyState != 4 && xhr.readyState != 0){
            xhr.abort();
        }
        xhr = $.ajax({
            url: 'ajax/progress.ftl',
            success: function(data) {
                //do something
            }
        });
    };

    var interval = setInterval(fn, 500);
); 

2
আপনি কি অরুনের উত্তর কপি করে পেস্ট করেছিলেন? কারণ দুটি কোড ব্লকের সম্ভাবনা হ'ল ঠিক একই, ব্যবধান এবং সমস্ত ...

@ user2700923 তার পোস্টটি ঠিক একই নয়। তার বক্তব্যটি হ'ল আমাদেরও রেডিস্টেট 0 পরীক্ষা করা উচিত However তবে এটি অরুনের উত্তরের মন্তব্য হিসাবে আরও বেশি উপযুক্ত হত।
স্টিফান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.