How to put a delay on a loop in Ruby?

前端 未结 2 1636
情书的邮戳
情书的邮戳 2020-12-31 08:32

For example, if I want to make a timer, how do I make a delay in the loop so it counts in seconds and do not just loop through it in a millisecond?

相关标签:
2条回答
  • 2020-12-31 08:52

    Somehow, many people think that putting a sleep method with a constant time interval as its argument will work. However, note that no method takes zero time. If you put sleep(1) within a loop, the cycle will surely be more than 1 second as long as you have some other content in the loop. What is worse, it does not always take the same time processing each iteration of a loop. Each cycle will take more than 1 second, with the error being random. As the loop keeps running, this error will contaminate and grow always toward positive. Especially if you want a timer, where the cycle is important, you do not want to do that.

    The correct way to loop with constant specified time interval is to do it like this:

    loop do
      t = Time.now
        #... content of the loop
      sleep(t + 1 - Time.now)
    end
    
    0 讨论(0)
  • 2020-12-31 08:53

    The 'comment' above is your answer, given the very simple direct question you have asked:

    1.upto(5) do |n|
      puts n
      sleep 1 # second
    end
    

    It may be that you want to run a method periodically, without blocking the rest of your code. In this case, you want to use a Thread (and possibly create a mutex to ensure that two pieces of code are not attempting to modify the same data structure at the same time):

    require 'thread'
    
    items = []
    one_at_a_time = Mutex.new
    
    # Show the values every 5 seconds
    Thread.new do
      loop do
        one_at_a_time.synchronize do
          puts "Items are now: #{items.inspect}"
          sleep 5
        end
      end
    end
    
    1000.times do
      one_at_a_time.synchronize do
        new_items = fetch_items_from_web
        a.concat( new_items )
      end
    end
    
    0 讨论(0)
提交回复
热议问题