JQuery ব্যবহার করে ব্যর্থ হওয়ার জন্য একটি এজেএক্স অনুরোধটি আবার চেষ্টা করার সর্বোত্তম উপায় কী?


107

সুডোকোড:

$(document).ajaxError(function(e, xhr, options, error) {
  xhr.retry()
})

এমনকি আরও ভাল কিছু ধরণের ব্যাক-অফ হবে-


1
আমি নিশ্চিত না যে এটি আদৌ সর্বোত্তম উপায় কিনা, তবে কেবল একটি মন্তব্য, তবে আপনি যদি নিজের অজ্যাক্সটিকে একটি ফুকশন থেকে কল করেন তবে আপনি এটি একটি প্যারামিটার দিতে পারেন tries, এবং ব্যর্থতার সাথে আপনি আপনার ফাংশনটি কল করেন tries+1tries==3বা অন্য কোনও সংখ্যায় কার্যকর করা বন্ধ করুন ।
Nanne


এখানে দুর্দান্ত সমাধান: stackoverflow.com/questions/6298612/…
জেরেমি এ। পশ্চিম

উত্তর:


238

এটার মতো কিছু:


$.ajax({
    url : 'someurl',
    type : 'POST',
    data :  ....,   
    tryCount : 0,
    retryLimit : 3,
    success : function(json) {
        //do something
    },
    error : function(xhr, textStatus, errorThrown ) {
        if (textStatus == 'timeout') {
            this.tryCount++;
            if (this.tryCount <= this.retryLimit) {
                //try again
                $.ajax(this);
                return;
            }            
            return;
        }
        if (xhr.status == 500) {
            //handle error
        } else {
            //handle error
        }
    }
});

12
আমি @ সুধিরের সমাধান নিয়েছি এবং এখানে গিথুবে একটি ret .retryAjax প্লাগইন তৈরি করেছি: github.com/mberkom/jQuery.retryAjax
মাইকেল বার্কম্পাস

2
এটি আমার জন্য কাজ করছে না। শর্তসাপেক্ষে এই.ট্রিস্টাউন্টটি সর্বদা 1
ব্যবহারকারী 304602

2
@ মিশেলবার্কম্পাস - আপনার প্লাগইন এখনও কাজ করে? এটি 2 বছরে কমিটগুলি পায়নি।
হেন্ডরিক

2
যদি অন্য কলব্যাক হ্যান্ডলারটি .successএই এজাক্স অনুরোধটি ফেরত ফাংশনটি কল করার সাথে সংযুক্ত থাকে তবে কি এই কাজ করবে ?
সমস্যাগুলি

17
জোড় যুক্ত tryCountএবং retryLimitঅত্যধিক। শুধুমাত্র 1 পরিবর্তনশীল ব্যবহার বিবেচনা করুন:this.retryLimit--; if (this.retryLimit) { ... $.ajax(this) ... }
ভ্লাদক্রাস

15

একটি পদ্ধতির একটি মোড়ক ফাংশন ব্যবহার করা হয়:

(function runAjax(retries, delay){
  delay = delay || 1000;
  $.ajax({
    type        : 'GET',
    url         : '',
    dataType    : 'json',
    contentType : 'application/json'
  })
  .fail(function(){
    console.log(retries); // prrint retry count
    retries > 0 && setTimeout(function(){
        runAjax(--retries);
    },delay);
  })
})(3, 100);

অন্য পদ্ধতির retriesউপর একটি সম্পত্তি ব্যবহার করা হবে$.ajax

// define ajax settings
var ajaxSettings = {
  type        : 'GET',
  url         : '',
  dataType    : 'json',
  contentType : 'application/json',
  retries     : 3  //                 <-----------------------
};

// run initial ajax
$.ajax(ajaxSettings).fail(onFail)

// on fail, retry by creating a new Ajax deferred
function onFail(){
  if( ajaxSettings.retries-- > 0 )
    setTimeout(function(){
        $.ajax(ajaxSettings).fail(onFail);
    }, 1000);
}

আর একটি উপায় ( জিআইএসটি ) - ওভাররাইড আসল $.ajax(ডিআরওয়াইয়ের পক্ষে ভাল)

// enhance the original "$.ajax" with a retry mechanism 
$.ajax = (($oldAjax) => {
  // on fail, retry by creating a new Ajax deferred
  function check(a,b,c){
    var shouldRetry = b != 'success' && b != 'parsererror';
    if( shouldRetry && --this.retries > 0 )
      setTimeout(() => { $.ajax(this) }, this.retryInterval || 100);
  }

  return settings => $oldAjax(settings).always(check)
})($.ajax);



// now we can use the "retries" property if we need to retry on fail
$.ajax({
    type          : 'GET',
    url           : 'http://www.whatever123.gov',
    timeout       : 2000,
    retries       : 3,     //       <-------- Optional
    retryInterval : 2000   //       <-------- Optional
})
// Problem: "fail" will only be called once, and not for each retry
.fail(()=>{
  console.log('failed') 
});

একটি বিন্দু বিবেচনা করছে নিশ্চিত$.ajax পদ্ধতি ইতিমধ্যেই আগে থেকেই আবৃত করা হয় নি অর্ডার দুইবার চলমান একই কোড এড়ানোর জন্য।


এগুলি স্নিপেটগুলি (যেমন রয়েছে) সেগুলি পরীক্ষা করার জন্য কনসোলে অনুলিপি-পেস্ট করতে পারেন


স্ক্রিপ্ট জন্য ধন্যবাদ। এটি aj .JaxSetup নিয়ে কাজ করে?
সেভবান üztürk

@ সেভবানিজটর্ক - আপনার অর্থ কী? শুধু চেষ্টা করুন :)
vsync

কিভাবে একটি মোড়ক গঠন করতে শেখানোর জন্য ধন্যবাদ! এটি আমি প্রয়োগ করতে ব্যবহৃত পুরাতন পুনরাবৃত্ত ফাংশন নকশাকে প্রহার করে।
ডিকোডার 7283

7

নীচে এই কোডটি দিয়ে আমি প্রচুর সাফল্য পেয়েছি (উদাহরণ: http://jsfiddle.net/uZSFK/ )

$.ajaxSetup({
    timeout: 3000, 
    retryAfter:7000
});

function func( param ){
    $.ajax( 'http://www.example.com/' )
        .success( function() {
            console.log( 'Ajax request worked' );
        })
        .error(function() {
            console.log( 'Ajax request failed...' );
            setTimeout ( function(){ func( param ) }, $.ajaxSetup().retryAfter );
        });
}

4
আমি কেবলমাত্র পরিবর্তনটিই সুপারিশ করব ফাংশন () "ফানক (প্যারাম) with দিয়ে 'ফানক ("' + প্যারাম "") "প্রতিস্থাপন করা That এইভাবে, আপনি প্যারামিটারটিকে স্ট্রিং এবং পিছনে রূপান্তর না করেই সরাসরি পাস করতে পারেন can , যা খুব সহজেই ব্যর্থ হতে পারে!
ফেবস্প্রো

@ ফ্যাবস্প্রো হয়েছে ধন্যবাদ!
নাবিল কাদিমি 25'15

7
এটি কি অন্তহীন লুপ নয়? প্রদত্ত প্রশ্নের একটি পুনরায় চেষ্টা আছে এবং সম্ভবত সার্ভারটি কখনই ফিরে আসবে না তা পূরণ করতে চাইছে ... আমি মনে করি এটি সত্যিই সেখানে থাকতে হবে
পান্ডাউড

3
jQuery.ajaxSetup () বিবরণ: ভবিষ্যতের Ajax অনুরোধগুলির জন্য ডিফল্ট মান সেট করুন। এর ব্যবহার বাঞ্ছনীয় নয়। api.jquery.com/jQuery.ajaxSetup
blub

2

কেউ যদি .done()তাদের এজ্যাক্স কল করার পরে কল করে তবে এই উত্তরগুলির মধ্যে কোনওটিই কাজ করে না কারণ আপনার কাছে ভবিষ্যতের কলটি সংযুক্ত করার সাফল্য পদ্ধতি নেই। সুতরাং যদি কেউ এটি করে:

$.ajax({...someoptions...}).done(mySuccessFunc);

তারপরে mySuccessFuncআবার চেষ্টা করার দরকার নেই। আমার সমাধানটি এখানে দেওয়া হয়েছে, যা এখানে @ সিজপাকের উত্তর থেকে ভারী নেওয়া হয়েছে । আমার ক্ষেত্রে আমি আবার চেষ্টা করতে চাই যখন AWS এর API গেটওয়ে 502 ত্রুটির সাথে প্রতিক্রিয়া জানায়।

const RETRY_WAIT = [10 * 1000, 5 * 1000, 2 * 1000];

// This is what tells JQuery to retry $.ajax requests
// Ideas for this borrowed from https://stackoverflow.com/a/12446363/491553
$.ajaxPrefilter(function(opts, originalOpts, jqXHR) {
  if(opts.retryCount === undefined) {
    opts.retryCount = 3;
  }

  // Our own deferred object to handle done/fail callbacks
  let dfd = $.Deferred();

  // If the request works, return normally
  jqXHR.done(dfd.resolve);

  // If the request fails, retry a few times, yet still resolve
  jqXHR.fail((xhr, textStatus, errorThrown) => {
    console.log("Caught error: " + JSON.stringify(xhr) + ", textStatus: " + textStatus + ", errorThrown: " + errorThrown);
    if (xhr && xhr.readyState === 0 && xhr.status === 0 && xhr.statusText === "error") {
      // API Gateway gave up.  Let's retry.
      if (opts.retryCount-- > 0) {
        let retryWait = RETRY_WAIT[opts.retryCount];
        console.log("Retrying after waiting " + retryWait + " ms...");
        setTimeout(() => {
          // Retry with a copied originalOpts with retryCount.
          let newOpts = $.extend({}, originalOpts, {
            retryCount: opts.retryCount
          });
          $.ajax(newOpts).done(dfd.resolve);
        }, retryWait);
      } else {
        alert("Cannot reach the server.  Please check your internet connection and then try again.");
      }
    } else {
      defaultFailFunction(xhr, textStatus, errorThrown); // or you could call dfd.reject if your users call $.ajax().fail()
    }
  });

  // NOW override the jqXHR's promise functions with our deferred
  return dfd.promise(jqXHR);
});

এই স্নিপেটটি ব্যাক-অফ হবে এবং ২ সেকেন্ড, তারপরে 5 সেকেন্ড, 10 সেকেন্ড পরে আবার চেষ্টা করবে, যা আপনি RETRY_WAIT ধ্রুবকটি সংশোধন করে সম্পাদনা করতে পারবেন।

এডাব্লুএস সমর্থন প্রস্তাব দিয়েছে যে আমরা পুনরায় চেষ্টা করব, যেহেতু এটি আমাদের জন্য কেবল একবার নীল চাঁদে ঘটে।


আমি এটিকে এখন পর্যন্ত সমস্ত উত্তরের মধ্যে সবচেয়ে দরকারী বলে মনে করেছি। যাইহোক, শেষ লাইনটি টাইপস্ক্রিপ্টে সংকলন প্রতিরোধ করে। আমি মনে করি না এই ফাংশনটি থেকে আপনার কিছু ফিরিয়ে দেওয়া উচিত।
ফ্রেডি

0

এটির জন্য এখানে একটি ছোট প্লাগইন রয়েছে:

https://github.com/execjosh/jquery-ajax-retry

অটো ইনক্রিমেন্টিংয়ের সময়সীমা এটির জন্য একটি ভাল সংযোজন হবে।

এটি বিশ্বব্যাপী ব্যবহার করতে কেবল own .জ্যাক্স স্বাক্ষর দিয়ে আপনার নিজস্ব ফাংশন তৈরি করুন, সেখানে এপিআই পুনরায় চেষ্টা করুন এবং আপনার নতুন ফাংশন দ্বারা আপনার সমস্ত aj .জ্যাক্স কলগুলি প্রতিস্থাপন করুন।

এছাড়াও আপনি সরাসরি aj .ajax প্রতিস্থাপন করতে পারেন, তবে আপনি আবার চেষ্টা না করে xhr কল করতে সক্ষম হবেন না।


0

লাইব্রেরিগুলি অ্যাসিক্রোনাস লোড করার জন্য যে পদ্ধতিটি আমার জন্য কাজ করেছিল তা এখানে রয়েছে:

var jqOnError = function(xhr, textStatus, errorThrown ) {
    if (typeof this.tryCount !== "number") {
      this.tryCount = 1;
    }
    if (textStatus === 'timeout') {
      if (this.tryCount < 3) {  /* hardcoded number */
        this.tryCount++;
        //try again
        $.ajax(this);
        return;
      }
      return;
    }
    if (xhr.status === 500) {
        //handle error
    } else {
        //handle error
    }
};

jQuery.loadScript = function (name, url, callback) {
  if(jQuery[name]){
    callback;
  } else {
    jQuery.ajax({
      name: name,
      url: url,
      dataType: 'script',
      success: callback,
      async: true,
      timeout: 5000, /* hardcoded number (5 sec) */
      error : jqOnError
    });
  }
}

তারপরে .load_scriptআপনার অ্যাপ থেকে কেবল কল করুন এবং আপনার সাফল্যের কলব্যাকটি নীড় করুন:

$.loadScript('maps', '//maps.google.com/maps/api/js?v=3.23&libraries=geometry&libraries=places&language=&hl=&region=', function(){
    initialize_map();
    loadListeners();
});

0

ডেমোউজারগুলির উত্তরটি জেপ্তোর সাথে কাজ করে না, যেহেতু এটি ত্রুটি ফাংশনে উইন্ডোটির দিকে নির্দেশ করছে। (এবং 'এটি' ব্যবহারের সেই উপায়টি যথেষ্ট সুরক্ষিত নয় কারণ তারা জানেন না যে তারা কীভাবে এজ্যাক্স প্রয়োগ করে বা তার প্রয়োজন নেই।)

জেপ্টো এর জন্য, আপনি নীচে চেষ্টা করতে পারেন, এখন পর্যন্ত এটি আমার পক্ষে ভালভাবে কাজ করে:

var AjaxRetry = function(retryLimit) {
  this.retryLimit = typeof retryLimit === 'number' ? retryLimit : 0;
  this.tryCount = 0;
  this.params = null;
};
AjaxRetry.prototype.request = function(params, errorCallback) {
  this.tryCount = 0;
  var self = this;
  params.error = function(xhr, textStatus, error) {
    if (textStatus === 'timeout') {
      self.tryCount ++;
      if (self.tryCount <= self.retryLimit) {
        $.ajax(self.params)      
        return;
      }
    }
    errorCallback && errorCallback(xhr, textStatus, error);
  };
  this.params = params;
  $.ajax(this.params);
};
//send an ajax request
new AjaxRetry(2).request(params, function(){});

অনুরোধটি প্রত্যাবর্তনযোগ্য তা নিশ্চিত করতে কনস্ট্রাক্টর ব্যবহার করুন!


0

আপনার কোড প্রায় পূর্ণ :)

const counter = 0;
$(document).ajaxSuccess(function ( event, xhr, settings ) {
    counter = 0;
}).ajaxError(function ( event, jqxhr, settings, thrownError ) {
    if (counter === 0 /*any thing else you want to check ie && jqxhr.status === 401*/) {
        ++counter;
        $.ajax(settings);
    }
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.