m.request发出太多请求

时间:2015-08-29 11:13:10

标签: mithril.js

我刚刚开始学习mithril,我正在尝试编写一个与RESTful API交互的简单前端。但是,当我在浏览器中加载它时,浏览器会发出< 30 GET请求' / posts'每秒!我不确定这是否是我的代码中的错误或秘密如何工作...如何让m.request在整个代码中发出一次请求,或者任意更新Post.list?

var Post = {
  model: function(data) {
    data = data || {};
    this.id = m.prop(data.id);
    this.text = m.prop(data.text);
    this.rating = m.prop(data.rating);
    this.created_at = m.prop(data.created_at);
    this.url = m.prop(data.url);
    this.title = m.prop(data.title);
    this.user_id = m.prop(data.user_id);
  },
  list: function() {
    return m.request({
      method: "GET",
      url: "/posts/",
      type: Post.model
    });
  }
}
var PostIndex = {
  controller: function() {
    this.posts = Post.list();
  },
  view: function(ctrl) {
    return [
      m("table.table", [ m("tbody", [
        ctrl.posts().map(function(post) {
          return m("tr", [
            m("td.heading", { onclick: m.route('/posts/' + post.id) }, [
              post.title,
              m("small", post.url)
            ]),
            m("td", [ m("small", post.user + ": " + post.created_at) ])
          ]);
        })
      ])])
    ];
  }
};

1 个答案:

答案 0 :(得分:2)

秘银在内部使用称为虚拟DOM的东西。这种方式的工作方式是存在DOM的内存模型,每当模型对象中的某些内容发生更改或用户与页面交互时,该模型都会更新。基本上,所有的时间。 这一切都发生在内存中,并经过优化,可以非常快速地运行。每次重新创建Virtual DOM时,它都会将自身与实际DOM进行比较,以查看是否存在任何差异。如果有什么不同,那么Mithril才会更新实际的DOM。这是使秘银如此快速的一部分。

我不是肯定的,但m.request可能会在view函数中被调用,它始终触发(更新虚拟DOM)。

ctrl.posts().map(function(post) {
      return m("tr", [.....

如果是这种情况,那么这里发生的是以下内容: ctrl.posts() - > Post.list() - > m.request

一种可能的解决方案是在完成执行后存储m.request的结果,然后在其他地方与存储的值相关联。 您可以将控制器代码更改为以下内容:

controller: function() {
    this.posts = m.prop([])
    Post.list().then(this.posts, console.log)
},

首先使用getter / setter函数初始化this.posts,该函数现在将返回一个空列表。 然后它调用m.request函数,该函数将一次发送GET请求。请求结束后,结果将传递给"然后"功能。 "然后"将函数作为参数:第一个 - 如果先前函数成功则该怎么做,第二个 - 如果失败则该怎么办。无论哪种方式,传递的函数都会自动接收上一个函数的结果,因此不需要明确指定。由于this.posts现在是一个通过传递参数设置的函数,这将自动设置this.posts和m.request调用的结果。

在此更改之后,当在视图函数中调用ctrl.posts时,将调用存储在变量中的内容,而不是每次都发送垃圾邮件m.request。

我现在正在自己学习秘银并度过了愉快的时光。我并不认为我描述的是这里发生的事情,但这听起来像是沿着这些方向发生的事情。如果我的建议没有帮助,可能是你的代码在每次调用ctrl.posts()时发送AJAX请求,直到第一个请求完成。所以我会在一段时间后检查请求是否停止,或者一直继续,因为这可能有助于缩小它的范围。