简体   繁体   English

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

[英]Non-blocking Timed event in Ruby like JavaScript setTimeout

I need to change a property on a class a few minutes after it it initialized. 我需要在初始化后几分钟更改类的属性。 I attempted to use sleep inside a function but it delayed execution of everything: 我试图在函数内部使用sleep但它延迟了所有事情的执行:

active = true

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

deactivate
puts active

What I was hoping would happen is true would log out first then two minutes later deactivate would log. 我希望会发生的事情是true会先退出然后两分钟后deactivate会记录。 However, what happens is deactivate then false log out after two minutes. 但是,发生的情况是deactivate然后在两分钟后false注销。

In JavaScript I would do something like: 在JavaScript中我会做类似的事情:

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

Using @ihaztehcodez's suggestion of a Thread I came up with the simple solution I was looking for: 使用@ ihaztehcodez建议的一个线程我想出了我正在寻找的简单解决方案:

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

His warning about persistence doesn't worry me in this case since I am using it for non-critical notifications. 在这种情况下,他对持久性的警告不会让我担心,因为我将它用于非关键通知。 If the execution was critical then storing something in a database like @spickermann said or using a library like @km-rakibul-islam suggested would be the better solution. 如果执行很关键,那么将某些内容存储在像@spickermann这样的数据库中,或者使用像@ km-rakibul-islam这样的库,这将是更好的解决方案。

Looks overkill for this task, but you can use delayed_job to run a task at a future time asynchronously. 对于此任务看起来有点过分,但您可以使用delayed_job在将来的时间异步运行任务。

  def deactivate
     puts 'deactivate'
     active = false
  end

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

Well, it seems to me (When I try this code) the active and deactivate is out of order. 嗯,在我看来(当我尝试这个代码时)活动和停用是乱序。 So why not do this?: 那么为什么不这样做呢?:

   active = true

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

   puts active
   deactivate

It works perfectly. 它完美地运作。

Why not just store the time until it is active? 为什么不直接存储它的时间?

Then there is no need to block, callback or run anything async at all. 然后根本不需要阻止,回调或运行任何异步。 When you store active_until in a datetime column in a database model, then it allows you keep track of changes and keep the current active status even over several different requests to the app: active_until存储在数据库模型的日期时间列中时,它允许您跟踪更改并保持当前active状态,甚至是对应用程序的几个不同请求:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM