Rails - 点击事件 - 如何处理 2 Ruby 方法之间的竞争条件?
Rails - on click event - how to deal with race condition between 2 Ruby methods?
在我看来,我有一个 link_to
元素 "Start Quiz!",它调用控制器方法(方法 A)来设置变量 "Phase" 并将用户重定向到新的静态页面。在我的 CoffeeScript 中,我有一个事件侦听器侦听对此 link_to
元素的点击。侦听器在后端调用不同的方法(方法 B),该方法使用 "Phase" 变量来执行某事。
问题:有时方法 B 会在控制器方法 A 更新之前尝试使用 "Phase" 变量!有没有人建议确保 "Phase" 变量在用于其他任何事情之前得到更新的最佳方法是什么?
我是 Rails 初学者,非常感谢任何指点。 :)
编辑:
"Phase" 是我用来跟踪当前测验问题的变量。它不依赖于任何输入,但每当呈现新页面(由单击按钮触发)时它都需要递增。
编辑2:
我现在试图通过向我的控制器引入一个实例变量标志 "is_changed" 并让方法 B 休眠直到标志设置为 true 来解决这个问题:
#method B:
def send_answers
until controller.index_changed?
sleep(0.5)
end
...
do sth.
end
#method A (in controller):
def initialize
@index_changed = false
end
def index_changed?
@index_changed
end
def set_index_changed!
@index_changed = false
end
def switch_to_next_question
...
self.phase += 1
if self.save
Thread.new do
@index_changed = true
ActiveRecord::Base.connection.close
end
else
...
end
end
它不起作用。方法A卡在睡眠中。我该如何解决?这是正确的方法吗?
是不是我的@index_changed变量的作用域有问题?我正在尝试创建一个可从 class 中的多个方法访问的实例变量,但对于此 class.
的每个实例都是单独的
好的,我通过找到一种顺序调用这 2 个方法的方法解决了这个问题。我最终完全消除了点击侦听器并直接调用 ActionCable 后端方法,这可以通过将其转换为 class 方法来实现:
class QuizDataChannel < ApplicationCable::Channel
#method B:
def self.send_answers #self. makes it a class method
#...
#do something with phase
end
end
在我的控制器中:
#method A:
def switch_to_next_question
#...
self.phase += 1
if self.save
QuizDataChannel.send_answers
else
#...
end
end
正如您最后看到的那样,我摆脱了所有这些:sleep
、新线程和 index_changed
标志。
在我看来,我有一个 link_to
元素 "Start Quiz!",它调用控制器方法(方法 A)来设置变量 "Phase" 并将用户重定向到新的静态页面。在我的 CoffeeScript 中,我有一个事件侦听器侦听对此 link_to
元素的点击。侦听器在后端调用不同的方法(方法 B),该方法使用 "Phase" 变量来执行某事。
问题:有时方法 B 会在控制器方法 A 更新之前尝试使用 "Phase" 变量!有没有人建议确保 "Phase" 变量在用于其他任何事情之前得到更新的最佳方法是什么?
我是 Rails 初学者,非常感谢任何指点。 :)
编辑: "Phase" 是我用来跟踪当前测验问题的变量。它不依赖于任何输入,但每当呈现新页面(由单击按钮触发)时它都需要递增。
编辑2: 我现在试图通过向我的控制器引入一个实例变量标志 "is_changed" 并让方法 B 休眠直到标志设置为 true 来解决这个问题:
#method B:
def send_answers
until controller.index_changed?
sleep(0.5)
end
...
do sth.
end
#method A (in controller):
def initialize
@index_changed = false
end
def index_changed?
@index_changed
end
def set_index_changed!
@index_changed = false
end
def switch_to_next_question
...
self.phase += 1
if self.save
Thread.new do
@index_changed = true
ActiveRecord::Base.connection.close
end
else
...
end
end
它不起作用。方法A卡在睡眠中。我该如何解决?这是正确的方法吗?
是不是我的@index_changed变量的作用域有问题?我正在尝试创建一个可从 class 中的多个方法访问的实例变量,但对于此 class.
的每个实例都是单独的好的,我通过找到一种顺序调用这 2 个方法的方法解决了这个问题。我最终完全消除了点击侦听器并直接调用 ActionCable 后端方法,这可以通过将其转换为 class 方法来实现:
class QuizDataChannel < ApplicationCable::Channel
#method B:
def self.send_answers #self. makes it a class method
#...
#do something with phase
end
end
在我的控制器中:
#method A:
def switch_to_next_question
#...
self.phase += 1
if self.save
QuizDataChannel.send_answers
else
#...
end
end
正如您最后看到的那样,我摆脱了所有这些:sleep
、新线程和 index_changed
标志。