jQuery Promise计时

时间:2015-08-23 14:24:47

标签: jquery promise

我有一个页面,我需要通过AJAX从数据库加载数据,我需要将元素加载到页面上。现在元素只需要加载到页面上一次,但数据需要多次加载。然后我有一个将数据放入元素的过程。

我已经调用了在下面的代码中加载元素elementsPromise时解析的承诺。

我的问题是关于如何制作和重新制作每次加载数据时解决的承诺。我有一个计划,但考虑到时间的变幻莫测,我不确定我的测试(jsFiddle here)是否可靠。因此,这个问题相当于“该方法应该有效吗?”:

我创建了一个函数,每次都返回一个promise和一个从它创建的变量。 e.g。

function getData() {
    def = new $.Deferred;
    // more code
    return def.promise();
}

dataPromise = getData();

然后我在上面有代码:

$.when(dataPromise, elementsPromise).done(function () {
    putDataInElements();
});

我担心第二次或更晚的时间putDataInElements()会立即开始,因为$.when不会等待重新定义dataPromise,而是会读取之前的状态在函数返回新的承诺之前。

请帮助,因为承诺使用一直困扰着我一段时间,虽然我认为我的方法会奏效,但我可以深入了解承诺如何运作的任何进一步见解。

PS。即使我的方法很好,如果有人能够解释为什么它没问题,我会很感激。

感谢。

1 个答案:

答案 0 :(得分:0)

我会采用稍微不同的方法,因为这是展示MVC分离和管理视图和模型(数据)的强大功能,由单个控制器绑定。

简介,即目标

我们的目标是生成一次生成的静态UI,但多次更新。

技术

我们将使用jQuery

实施

我们假设我们的申请由3个主要部分组成:

  • 模型 - 数据
  • 查看 - HTML / DOM
  • 控制器 - 合并和管理两个
  • 的东西

其余的将由服务构成,对于我们的例子,这将是jQuery提供的方法,从这里开始将被称为JQ。

引导代码

//controller
function Ctrl() {
   this.viewRendered = false;
}

Ctrl.prototype.init = function() {
  // magic happens here

  // $http is a promise
  var data = $http.get("http://my-data-endpoint.com/params");

  // when we get something back
  // 'data' is your model
  $.when(data, function(data) {

    // cache the jQuery container to prevent repetitive search
    // it's also your view, get to know each other - it'll be worth your while
    var $container = $("#dataContainer");

    //if the view was already rendered, let's fill it with the new data
    if(this.viewRendered) {
       var $items = $container.find("li");
       $items.each(function(i, el) { //notice the inverted $.each syntax
         $(el).text(data[i]); //we put in the data, according to its placement, assuming it's symmetric
       });
    } else {
    //if the view havn't been rendered yet - let's create it via the data
    data.forEach(function(el) {
      $container.append("<li>" + el.text + "</li>");
    });
    this.viewRendered = true;
  }
  }.bind(this));
}

var ctrl = new Ctrl();
ctrl.init();

HTML

<ul id="dataContainer"></ul>

解释

由于承诺本质上是单身人士,所以你提出的这种碰撞不会发生。

但是,您不需要使用延迟对象,因为jQuerys本机$ http服务及其派生也是延迟的,所以只需将这些调用直接传递到$ .when语句中:

var def = $.get("http://your-data-endpoint.com/whatevs");

$.when(def).done(function(data) {
  ...
});

我们的主要目标是创建一个3部分实体,它有2个部分:视图和模型,它是应在视图中表示的数据。

然后我们创建一个带有标志的控制器,让我们知道视图是否已被调用,并选择正确的渲染方法:

  • 按提供的数据创建视图
  • 将数据应用于渲染视图。

您可以进一步抽象它,并将逻辑与您的控制器分开,即 - 允许您的视图根据预定义的模板自动呈现提供的数据,与angularJS或反应管理他们的视图相同,但我认为它太过分了。

希望它足够清楚。