Ruby中的非阻塞定时事件,如JavaScript setTimeout

时间:2015-10-03 04:21:39

标签: javascript ruby-on-rails ruby

我需要在初始化后几分钟更改类的属性。我试图在函数中使用sleep,但它延迟了所有内容的执行:

active = true

def deactivate
  sleep 120
  puts 'deactivate'
  active = false
end

deactivate
puts active

我希望发生的事情是true会先退出,然后两分钟后deactivate会记录。但是,发生的情况是deactivate然后false在两分钟后退出。

在JavaScript中我会做类似的事情:

var active = true;
setTimeout(function(){
  console.log('deactivate');
  active = false;
},120000);
console.log(active);

4 个答案:

答案 0 :(得分:3)

使用@ ihaztehcodez建议的线程我想出了我想要的简单解决方案:

Thread.new do
  sleep 120
  puts 'deactivate'
  active = false
end

在这种情况下,他对持久性的警告不会让我担心,因为我将它用于非关键通知。如果执行很关键,那么将某些内容存储在像@spickermann这样的数据库中,或者使用像@ k-m-rakibul-islam这样的库,这将是更好的解决方案。

答案 1 :(得分:2)

对此任务看起来有点过分,但您可以使用delayed_job异步运行任务。

  def deactivate
     puts 'deactivate'
     active = false
  end

  active = true
  handle_asynchronously :deactivate, :run_at => Proc.new { 2.minutes.from_now }

答案 2 :(得分:1)

嗯,在我看来(当我尝试此代码时),活动和停用是乱序。那么为什么不这样做呢?:

   active = true

   def deactivate
     sleep 120
     puts 'deactivate'
     active = false
   end

   puts active
   deactivate

效果很好。

答案 3 :(得分:1)

为什么不将时间存储到活动状态之前?

然后根本不需要阻止,回调或运行任何异步。当您将active_until存储在数据库模型的日期时间列中时,它可以让您跟踪更改并保持当前active状态,甚至可以对应用程序发出几个不同的请求:

def active
  active_until.blank? || Time.current < active_until
end

def deactivate
  update_columns(active_until: 2.minutes.since)
end