【问题标题】:jQuery deferred objects and running functions in orderjQuery 按顺序延迟对象和运行函数
【发布时间】:2012-04-25 10:03:57
【问题描述】:

我有这段代码将使用 $.ajax 加载 css/js/jst(javascript 模板),我想让它在请求后运行一个请求,一次只运行一个,并且异步执行。

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() 将接受一个函数作为可选参数,并在从构造函数返回之前运行该函数,这就是问题所在,但我不知道有一个解决方案可以做什么我要。

问候!

【问题讨论】:

    标签: jquery ajax deferred


    【解决方案1】:

    我终于做到了:

    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!");
    
    });
    

    问候!

    【讨论】:

      猜你喜欢
      • 2014-09-15
      • 2016-03-24
      • 2013-04-29
      • 2016-12-01
      • 2018-12-10
      • 1970-01-01
      • 2015-06-23
      • 2011-12-17
      • 1970-01-01
      相关资源
      最近更新 更多