小编san*_*e89的帖子

JavaScript:为什么只有在将return函数赋给变量时才会发生闭包?

阅读之后你甚至不知道JSJavaScript:Core我仍然无法理解下面代码的行为.

为什么,当我调用时counter()(),我没有得到闭包,但是如果我给结果分配一个变量counter(),比如var getClosure = counter(),我在调用时得到一个闭包getClosure()

function counter() {

    var _counter = 0;

    function increase() { return _counter++ }

    return increase;
}

// Double ()() to call the returned function always return 0, so no closure. 
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0
counter()() // returns 0

var createClosure = counter();

createClosure() // returns 0
createClosure() // returns 1
createClosure() // returns 2
createClosure() …
Run Code Online (Sandbox Code Playgroud)

javascript closures

40
推荐指数
2
解决办法
2039
查看次数

rails 3在过滤之前全部跳过

任何人都可以告诉我如何在rails 3中过滤掉之前的所有过滤器.

在rails 2.x中我们可以做到

skip_filter filter_chain
Run Code Online (Sandbox Code Playgroud)

但是rails 3中不再支持filter_chain.

谢谢

ruby-on-rails

11
推荐指数
3
解决办法
8154
查看次数

Rails/ActiveRecord:避免两个线程同时使用锁更新模型

假设我需要确保ModelName两个不同的Rails线程不能同时更新; 例如,当发布到应用程序的webhooks尝试在运行某些其他代码的同时修改它时,就会发生这种情况.

Per Rails文档,我认为解决方案是使用model_name_instance.with_lock,也开始新的事务.

这样可以正常工作并防止同时向模型更新,但它不会阻止其他线程在with_lock块运行时读取该表行.

我可以with_lock通过这样做来证明这并不妨碍其他READS:

  • 打开2个导轨控制台;

  • 在控制台1上键入类似的内容 ModelName.last.with_lock { sleep 30 }

  • 在控制台2上,键入ModelName.last.你将能够阅读模型没有问题.

  • 在控制台2上,键入ModelName.update_columns(updated_at: Time.now).您将看到它将在等待30秒锁定到期之前到期.

这证明锁不会阻止读取,据我所知,没有办法锁定数据库行被读取.

这是有问题的,因为如果2个线程在同一时间运行相同的方法,并且我必须决定运行with_lock关于模型数据的某些先前检查的块,则线程2可能正在读取将很快被线程1更新的过时数据在它完成with_lock已经运行的块之后,因为线程2 with_lock在线程1中的块正在进行时CAN读取模型,它只能因为锁定而无法更新它.

编辑:我找到了这个问题的答案,所以你可以在这里停止阅读并直接进入下面:)

我的一个想法是开始with_lock阻止对模型发出无害更新(model_instance_name.update_columns(updated_at: Time.now)例如),然后用a跟随它以model_name_instance.reload确保它获得最新的数据.因此,如果两个线程同时运行相同的代码,则只有一个线程能够发出第一个更新,而另一个线程需要等待释放锁定.一旦它被释放,它将遵循以model_instance_name.reload确保获得由另一个线程执行的任何更新.

问题是这个解决方案对我来说似乎过于苛刻,而且我不确定我应该在这里重新发明轮子(我不知道我是否缺少任何边缘情况).如何确保当两个线程在同一时间运行完全相同的方法时,一个线程等待另一个线程完成甚至读取模型?

activerecord ruby-on-rails

10
推荐指数
1
解决办法
4691
查看次数

(Rails)何时使用ActiveRecord的.where和.select

我在我的Rails应用程序User中有一个名为的Model ,它有一个属性name

比方说,我想找到的所有Usersname特定的字符串相匹配.

在Rails控制台中,我可以这样做:

选项1

User.where("name LIKE 'string'")

这非常快.

方案2

User.select{|u| u.name == "string"}

这非常慢.它适用于一个小型数据库,但如果你有数十万用户,这似乎首先尝试将所有用户加载Users到内存中,然后在块中迭代它们.

这是否意味着选项2总是错误的?什么是正确的用例.select,什么时候更好.where

我在我的应用程序中编写了一堆代码正常使用.select,但现在我尝试在一个非常大的表上使用我看到我可能做错了什么.

activerecord ruby-on-rails ruby-on-rails-3

7
推荐指数
1
解决办法
5440
查看次数

Google Cloud SQL 很慢:具有 10GB RAM 的 mysql 实例比配置有 125MB ram 的 Macbook Pro 慢 20 倍

我们按照 Google Cloud SQL 指令转储了我们的表,并将其导入到第二代 Google Cloud SQL 实例中。

我们很高兴看到我们的数字将如何在“谷歌硬件”上运行。

在使用 Apache 对我们的 Rails 应用程序进行压力测试之后 ab并看到完成时间高 150 毫秒后,我们注意到 ActiveRecord 在相同页面中比我们的生产服务器(裸机)多花费 30 毫秒到 50 毫秒。

当我们深入挖掘时,真正让我们大吃一惊的是像这样的简单计数查询:

GOOGLE CLOUD SQL - db-n1-standard-4 (4vcpu and 15GB RAM)

1. Cold query

mysql> SELECT COUNT(*) FROM `event_log`;
+----------+
| COUNT(*) |
+----------+
|  3998050 |
+----------+
1 row in set (19.26 sec)

2. Repeat query

mysql> SELECT COUNT(*) FROM `event_log`;
+----------+
| COUNT(*) |
+----------+
|  3998050 |
+----------+
1 row in set (1.16 …
Run Code Online (Sandbox Code Playgroud)

mysql

6
推荐指数
1
解决办法
3629
查看次数

Vue.js应用程序可在开发中工作,但无法在Rails 5.2.0 / Webpacker的生产环境中安装模板-黑屏,控制台无错误

我正在使用Rails 5.2.0和Webpacker gem来部署Vue应用程序。

show.html.erb文件非常简单:

<div data-behavior="vue-app"><MyComponent></MyComponent></div>

然后在我的入门包中,包是packs / my_vue_app.js:

import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm'
Vue.use(TurbolinksAdapter);
import MyComponent from '../components/my_app/index.vue'

document.addEventListener('turbolinks:load', () => {

  var element = $('[data-behavior="vue-app"]');

  if(!element) { return };

  console.log('Initializing Vue');

  const app = new Vue({
    el: element[0],
    data: {

    },
    components: { MyComponent }
  })
})
Run Code Online (Sandbox Code Playgroud)

在开发中,一切正常。该应用程序已安装且正常运行。

但是在生产中,在页面加载和JS运行之后,<div data-behavior="vue-app">将从分页中删除,仅保留<!-- -->在原处。

在控制台中,绝对没有错误。我可以使用DevTools确认pack js文件已加载并已解析,因为console.log已打印在控制台中。

哎呀,Vue运行正常的证明是,在<div>解析JS之后,已从DOM中删除了整个安装位置。

最奇怪的是,我可以通过在console.log行上附加调试器并在调试器暂停执行时将其关闭来使应用程序挂载ONCE。即使当时我看到应用程序正在安装也很艰难,但后来却无法安装它,甚至再也不用调试器了……这真的非常奇怪。

这些是package.json的版本:

"vue": "^2.5.16", "vue-loader": "14.2.2", "vue-template-compiler": "^2.5.16",

Rails应用程序是全新的,除了默认设置外没有其他配置。

Webpacker gem是3.5.3,Rails是5.2.0。

在此上花了很长时间之后,我才发现以下github问题:https : //github.com/rails/webpacker/issues/1520 …

ruby-on-rails webpack vue.js webpacker

5
推荐指数
2
解决办法
1299
查看次数

Rails 5:使用带有参数的 form_with 预填充搜索表单输入,而无需为每个字段手动执行此操作

假设我们有一个简单的搜索表单,它提交一个用于搜索/过滤的 GET 请求:

<%= form_with(scope: :search, url: url_for, local: false, method: :get) do |f| %>
  <%= f.text_field :title %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

当我们使用form_with(或旧的form_forActiveRecord 对象时,所有字段都会自动预先填充 AR 对象属性的当前值。

但在上面的示例中,如果我们仅使用范围(在本例中为search),则当我们使用如下 URL 打开页面时,不会发生这种情况:

http://localhost:3000/blog?search%5title%5D=test

即使 URL 很难为我们填充 Rails params[:search]{title: 'test'}它仍然需要手动传递每个字段的值,如下所示:

<%= f.text_field :title, value: params.dig(:search, :title) %>

随着搜索表单的增长,这变得非常乏味且容易出错,并且这似乎是一个常见的要求,我无法相信没有一种更“轨道的方式”可以在不诉诸表单对象设计模式之类的情况下做到这一点。

是否有任何自动方法可以预先填充这些输入,而不必从参数手动传递值?

ruby-on-rails

5
推荐指数
1
解决办法
919
查看次数

如何在 React Native 中使用异步数据(AsyncStorage)初始化 MobX 存储

我们创建了一个简单的 MobX 存储来保存对象。每次 fooObject 更改时,此 MobX 存储也会与 AsyncStorage 同步:

import { observable } from 'mobx';

class FooStore {
  @observable fooObject = {};

  setFooObject(newFooObject) {
    this.fooObject = newFooObject;
    this.syncWithAsyncStorage();
  }

  syncWithAsyncStorage() {
    AsyncStorage.setItem('fooObject', JSON.stringify(this.fooObject));
  }
Run Code Online (Sandbox Code Playgroud)

然后,应用程序中的各个屏幕都会使用此 mobx 商店。

正如您所看到的,我们使用 RNAsyncStorage来始终存储 的当前状态,RN 是一种 LocalStorage,但对于本机应用程序而言fooObject

问题是:当应用程序关闭时,我们会丢失 FooStore 状态,因此我们想要检索对 AsyncStorage 所做的最后一次“保存”(已持久保存)。

问题是 AsyncStorage(正如其名称所示)是一个 ASYNC 函数,我们不能等待 FooStore 构造函数中的承诺解析。

如何根据 AsyncStorage 解析的返回值来完成此 MobX 存储的初始状态初始化?

我们考虑在 FooStore 中编写一个初始化方法(异步方法),如下所示:

async initializeFromAsyncStorage() {
  this.fooObject = await JSON.parse(await AsyncStorage.getItem('fooObject'));
}
Run Code Online (Sandbox Code Playgroud)

然后在我们的根 App.js 中的应用程序初始化时调用此方法。

但我不确定这是否会带来意想不到的副作用,以及这是否是惯用的 mobx/react-native。

react-native mobx

4
推荐指数
1
解决办法
6451
查看次数

Ruby:使用 class_eval 定义常量只能通过 const_get 找到,而不能直接通过 :: lookup 找到

给定一个 User 类:

class User
end
Run Code Online (Sandbox Code Playgroud)

我想使用.class_eval. 所以:

User.class_eval { AVOCADO = 'fruit' }
Run Code Online (Sandbox Code Playgroud)
  1. 如果我尝试通过 访问它User::AVOCADO,我得到uninitialized constant User::AVOCADO,但User.const_get(:AVOCADO)有效。为什么?

  2. 如果我在included方法中的 Rails 关注中定义一个常量并将关注包含在User类中,我可以通过常规::查找访问它。例如:

module FruitConcern
  extend ActiveSupport::Concern

  included do
     AVOCADO = 'fruit'
  end

end

class User
  include FruitConcern
end

User::AVOCADO
=> 'fruit'
Run Code Online (Sandbox Code Playgroud)

但是,查找ActiveSupport::Concern的源代码included只需将该块存储在实例变量 ( @_included_block) 中,然后它append_features就会覆盖will call base.class_eval(&@_included_block)

那么,如果它只是User.class_eval使用同一个块调用,为什么User::AVOCADO在该included块内定义常量时有效,而当我User.class_eval { AVOCADO = 'fruit' …

ruby ruby-on-rails

3
推荐指数
2
解决办法
127
查看次数

Hotwire/Turbo Frames:为什么 `target: "_top"` 不通过 fetch 请求页面?

我正处于将 Rails 应用程序从 Turbolinks/rails-ujs(使用产生奇迹的良好 ol 视图)迁移到 Hotwire/Turbo 的早期阶段js.erb

想象一个users/index.html.erb带有搜索表单和结果表的传统页面:

<%= form_with(scope: :search, url: url_for, method: :get, data: { turbo_frame: "users_table" }) do |f| %>

  <%= f.search_field :name %>

<% end %>

<%= turbo_frame_tag("users_table") do %>
  
  <% @users.each do |user| %>
    <%= link_to user.name, user, target: :_top %>
  <% end %>

  <%== pagy_bootstrap_nav(@pagy) %>

<% end %>
Run Code Online (Sandbox Code Playgroud)

因此,上面的搜索表单可以更新下面的 Turbo_frame_tag,而无需重新加载整页(这可以根据需要保留表单中的焦点和状态)。

Turbo_frame_tag 内的每个链接都应导航到 /users/show,替换整个页面。由于target: :_top每个链接中都包含该属性,因此它有效。

然而,用户体验却受到了影响。使用 Turbolinks,users_table 内的每个链接都会发出 AJAX 导航,取代“正文”,感觉非常非常敏捷。使用 Turbo/Hotwire,我可以在开发工具中看到,只有分页(在 Turbo 框架内)和表单提交(由于 Turbo_frame 属性)正在使用 获取fetch …

ruby-on-rails hotwire-rails hotwire

3
推荐指数
1
解决办法
2317
查看次数

即使调用 destroy(),Vue.js 也会发生 Turbolinks 内存泄漏 - 浏览器始终保留对 vue 实例应用程序的引用

我有一个使用 Turbolinks 的 Rails 应用程序。如果您不熟悉,turbolinks 会使documentwindow对象始终保持不变(页面永远不会刷新),并且它会通过 AJAX 拦截所有链接点击并替换 body 标记。

当在安装了 Vue 应用程序的页面之间导航时,这是我们观察到的内存/节点模式(它会增长到无穷大):

在此输入图像描述

正如您所看到的,在每次页面更改时,内存只会增加,而不会被回收。

我们的应用程序使用https://github.com/jeffreyguenther/vue-turbolinks,基本上是这样的代码:

beforeMount: function() {
  if (this === this.$root && this.$el) {
    document.addEventListener('turbolinks:visit', function teardown() {
      this.$destroy();
      document.removeEventListener('turbolinks:visit', teardown);
    })

    // cache original element
    this.$cachedHTML = this.$el.outerHTML;

    // register root hook to restore original element on destroy
    this.$once('hook:destroyed', function() {
      if( this.$el.parentNode )
        this.$el.outerHTML = this.$cachedHTML
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我在 Vue 应用程序上或其他任何地方都没有任何参考window(实例化代码只是new Vue({ options});没有全局变量,使用 const/let 的现代代码。

没有 …

javascript turbolinks vue.js

1
推荐指数
1
解决办法
1201
查看次数