0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

jQueryのDeferredを用いたAjaxでRetryを実装

Last updated at Posted at 2019-06-05

要件

  • AJAXで所定のURLにアクセスする
  • アクセスに成功した時、JSONデータを返す
  • アクセスに失敗した時、5回、再試行を繰り返す
  • 再試行にも失敗した場合、タイムアウトエラーを返す

実装

動作するためにjQueryが必要です。
筆者環境は「jquery-1.11.3」です。
なるべく汎用的に使いまわせるよう意識して書きました。

(function($){
'use strict';

var CONST = {
  'JSON' : {
    'PATH' : "/api/v1/items/data.json", // <- このあたりのURLをお使いの環境に合わせて変更してください
  },
};

Object.freeze(CONST);

/**
 * connect Ajax
 *
 * @param string targetPath
 * @param string method     ["GET", "POST"]
 * @param string dataFormat ["json", "jsonp", "xml", "html", "script", "text"]
 */
function connectAjax(targetPath, method, dataFormat)
{
  var maxRetries = 5; // 最大リトライ回数

  var retries = 0; // 現在のリトライ回数
  var retryTime = 1000; // リトライの間隔 ミリ秒

  var defer = $.Deferred();

  $.ajax({
    type : method,
    url : targetPath,
    dataType : dataFormat,
    cache : false,
    timeout : retryTime,
    success : defer.resolve,
    error : function(jqXHR, textStatus, errorThrown){
              if(retries < maxRetries){
                var _this = this;
                retryTime = retryTime * 2; // リトライを繰り返すごとにリトライ間隔を延長します
                _this.timeout = retryTime;
                console.warn("Connection Faild. Retry After " + retryTime + " (ms)");

                retries++;
                setTimeout(function(){ $.ajax(_this) }, retryTime); // retry begin
              }
              else {
                console.warn("Connection Timeout.");
                console.warn(jqXHR.status + " " + jqXHR.statusText);
                console.warn(showException(jqXHR.status, textStatus));

                defer.reject(); // retry end
              }
            },
  });

  return defer.promise();
}

function responceMessages()
{
   return {
     '400' : "Server understood the request, but request content was invalid.",
     '401' : "Unauthorized access.",
     '403' : "Forbidden resource can't be accessed.",
     '500' : "Internal server error.",
     '503' : "Service unavailable."
   };
}

function exceptionMessages()
{
   return {
     'parsererror' : "Parsing JSON Request failed.",
     'timeout'     : "Request Time out.",
     'abort'       : "Request was aborted by the server",
   };
}

function responceMessage(responceCode)
{
  var resMsgs = responceMessages();

  var msg = responceCode + " : ";
  var resMsg = resMsgs[responceCode];

  resMsg = isset(resMsg) ? resMsg : "An Unknown Error Occurred.";

  return msg + resMsg;
}

function exceptionMessage(textStatus)
{
  var exMsgs = exceptionMessages();

  var msg = textStatus + " : ";
  var exMsg = exMsgs[textStatus];

  exMsg = isset(exMsg) ? exMsg : "An Unknown Error Occurred.";

  return msg + exMsg;
}

function showException(responceCode, textStatus)
{
  var resMsg = responceMessage(responceCode);
  var exMsg = exceptionMessage(textStatus);

  return resMsg + "\n" + exMsg;
}

function loadJson(jsonPath)
{
  return connectAjax(jsonPath, "GET", "json");
}

function getItemList()
{
  return loadJson(CONST.JSON.PATH);
}

})(jQuery);

使い方

$(function(){
  var itemList = getItemList(); // ajax connect

  itemList.done(function(data){
    console.log(data);
    // ここにAJAX成功時にやりたいことを書きます
  })
  .fail(function(){
    console.log('Failed');
    // リトライにすべて失敗した後に、ここに書いた内容が走り出します
  });
});

参考にしたURL

https://qiita.com/toxxhixx/items/7b0e77654a19a670722f
https://qiita.com/mounntainn/items/37407e1ced0ce8c23101
https://iww.hateblo.jp/entry/20160804/setTimeout
https://stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery
https://stackoverflow.com/questions/377644/jquery-ajax-error-handling-show-custom-exception-messages

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?