2012-04-25 15 views
0

$ .ajaxを使用してcss/js/jst(javascriptテンプレート)をロードするこのコードは、リクエスト後にリクエストを実行するようにしたいです。それを非同期的に行うことです。jQuery遅延オブジェクトと実行関数を順番に

var getStuff = function(resources, progressCallback, errorCallback, successCallback, doneCallback){ 

    var deferreds = []; 
    var deferreds_progressCallback = []; 
    var len = resources.length; 

    for(var idx = 0; idx < len; idx++){ 

    var resource = resources[idx]; 

    var dfd = jQuery.Deferred(function(self){ 
     self.notify(resource); 
     (function(resource){ 
     jQuery.ajax({ 
      cache: false, 
      url: resource, 
      dataType: 'text', 
      error: function(xhr, status, error){ 
      self.reject(resource); 
      }, 
      success: function(data, status, xhr){ 
      if(typeof(data) != 'string'){ 
       console.log(typeof(data)); 
      } 
      if(resource.match(/.css$/)){ 
       $('head').append("<style type='text/css'>" + data + "</style>"); 
      }else if(resource.match(/.jst$/)){ 
       var templates_div = jQuery("<div style='display:none;'></div>").appendTo('body'); 
       templates_div.append(data); 
      }else if(resource.match(/.js$/)){ 
       jQuery.globalEval(data); 
      } 
      self.resolve(resource); 
      } 
     }); 
     })(resource); 
    }); 

    deferreds.push(dfd); 
    deferreds_progressCallback.push(resource); 

    } 

    deferreds.reverse(); 
    deferreds_progressCallback.reverse(); 

    (function iterateWhen(){ 
    if(len--){ 
     jQuery.when(deferreds[len]) 
     .then(function(resource){ 
     successCallback(resource); 
      iterateWhen(); 
     }) 
     .fail(function(resource){ 
     errorCallback(resource); 
     }) 
     .progress(function(resource){ 
     progressCallback(resource); 
     }); 
    }else{ 
     doneCallback && doneCallback(); 
    } 
    }()); 

} 

このコードは、起動時にすべての要求を実行します。これは、deferred.resolve()が呼び出されるまで待機しますが、iterateWhen()ループがdeferreds []に対して反復を開始するのを待機しません。

jQueryのドキュメントによれば、$ .Deferred()はオプションの引数として関数を受け取り、その関数をコンストラクタから返す前に実行するので、それは問題ですが、私はそれを行う解決法を知らない私が望むもの

よろしくお願いいたします。

答えて

0

私は最終的に、このようにそれをやった:

function getStuff(resources, progressCallback, errorCallback, successCallback, doneCallback){ 

    function inject(resource){ 
    var dfd = jQuery.Deferred(); 
    dfd.notify(resource); 

    jQuery.ajax({ 
     cache: false, 
     url: resource, 
     dataType: 'text', 
     error: function(xhr, status, error){ 
     dfd.reject(resource); 
     }, 
     success: function(data, status, xhr){ 
     if(resource.match(/.css$/)){ 
      $('head').append("<style type='text/css'>" + data + "</style>"); 
     }else if(resource.match(/.jst$/)){ 
      $('body').append("<div style='display:none;'>" + data + "</div>"); 
     }else if(resource.match(/.js$/)){ 
      jQuery.globalEval(data); 
     } 
     dfd.resolve(resource); 
     } 
    }); 

    return dfd; 
    }; 

    var len = resources.length; 
    resources.reverse(); 

    (function iterateWhen(){ 
    if(len--){ 
     inject(resources[len]) 
     .then(function(resource){ 
     successCallback && successCallback(resource); 
     iterateWhen(); 
     }) 
     .fail(function(resource){ 
     errorCallback && errorCallback(resource); 
     }) 
     .progress(function(resource){ 
     progressCallback && progressCallback(resource); 
     }); 
    }else{ 
     doneCallback && doneCallback(); 
    } 
    }()); 

} 

だから、あなたはこのようにそれを呼び出す必要があります:

getStuff([ 

    /*Load .JS, .JST and .CSS files*/ 
    /*Only same-domain request!*/ 
    'foo/bar.js', 
    'bar/foo.css' 

], function(resource){ /*Progress callback*/ 

    console.log("Loading " + resource); 

}, function(resource){ /*Errors callback*/ 

    console.log("Error while loading " + resource); 

}, function(resource){ /*OK callback*/ 

    console.log("Loaded " + resource); 

}, function(){ 

    console.log("Finished loading .js, .jst and .css files!"); 

}); 

よろしく!

関連する問題