处理针对AJAX调用的超出范围的变量

时间:2015-04-23 20:40:42

标签: javascript ajax

我有以下代码:

var User = {
  get: function (options) {
    var self = this;

    $.ajax({
      url: options.url,
      success: function (data, response) {
        self.nextPageUrl = data.pagination.next_page;
        options.success(data, response);
      }
    });
  },
  nextPage: function (success) {
    this.get({
      url: this.nextPageUrl, 
      success: success
    });
  }
}

User.get({
  url: 'https://cache.getchute.com/v2/albums/aus6kwrg/assets',
  success: function (data, response) {
    // Through `data.pagination.next_page` I can get the URL
    // of the next page.
  }
});

User.nextPage({
  success: function (data, response) {
    // Here I want to make the same request but using the next_page
    // based on the next related to the previous' one.
  }
});

问题

基本上,我想基于前驱请求(nextPage())执行User.get()操作,但由于其异步性,nextPage()方法不知道{{1 property-it按预期返回this.nextPageUrl

最后,问题是:有人能想出一种方法来保持当前的语法流程但是解决这种方法吗?实际上,有办法吗?

不,我无法发出同步请求。

一般知识

我想使用事件机制来解决这个问题:当发出请求并调用undefined时,尝试收听 x秒发出的事件,然后我希望.nextPage()属性在该基于事件的范围内可用。

你们有什么想法?

免责声明: this.nextPageUrl的逻辑由服务器预处理,然后才会发送到客户端。我没有选择使用递增/递减行为操作。

如果您想要解决此问题,请click here for the jsFiddle

3 个答案:

答案 0 :(得分:1)

在发出异步请求之前,您可以获取对User对象的引用。

var User = {
    get: function (options) {
    var self = this;
    $.ajax({
        url: options.url,
        success: function (data, response) {
          self.nextPageUrl = data.pagination.next_page;
          options.success(data, response);
        }
    });
},

答案 1 :(得分:1)

<强> jsFiddle Demo

有几种选择。您可以绑定属性的setter以同时调用<ol start="0"> <li>Html Tutorial</li> <li>Mongodb Tutorial</li> <li>Python Tutorial</li> </ol> ,您可以每隔n毫秒从调用nextPage进行轮询,直到填充nextPageUrl属性,您可以使用promise,您可以使用nextPageQueue。

我认为队列可能是完成此任务的最简单形式。我也认为让User在这种情况下存储一些局部变量可能是有用的,并且函数对象的使用可能更加内联。

看起来像这样

nextPage

你的电话不会改变。

var User = new function(){
  var pageQueue = [];
  var get = this.get = function (options) {
    $.ajax({
      url: options.url,
      dataType: 'JSON',
      success: function (data, response) {
        options.success(data, response);
        var nextPageUrl = data.pagination.next_page;
        if( pageQueue.length > 0 ){
         pageQueue[0](nextPageUrl);
         pageQueue.splice(0,1);
        }
      }
    });
  };
  var nextPage = this.nextPage = function (options) {
    pageQueue.push(function(nextPageUrl){
      get({
        url: nextPageUrl,
        success: options.success
      });
    });
  };
};

答案 2 :(得分:0)

您可以修改get方法并完全删除nextPage方法:

var User = {
  url: 'https://cache.getchute.com/v2/albums/aus6kwrg/assets',
  get: function (options) {
    var self = this;

    self.pageXhr = $.ajax({
      url: self.nextPageUrl ? self.nextPageUrl : self.url,
      dataType: 'JSON',
      success: function (data, response) {
        self.nextPageUrl = data.pagination.next_page;
        self.pageXhr = false;
        options.success(data, response);
      }
    });
  }
}

然后,无论何时调用User.get,它都将调用当前页面或下一页。我不确定何时需要获取后续页面的上下文,但如果您需要排队请求,则可以在触发下一个请求之前等待现有请求完成。例如:

if (self.pageXhr) {
   self.pageXhr = self.pageXhr.then(function() {
      return $.ajax({
          url: self.nextPageUrl ? self.nextPageUrl : self.url,
          dataType: 'JSON',
          success: function (data, response) {
            self.nextPageUrl = data.pagination.next_page;
            options.success(data, response);
          }
      });
   });
}