Ruby - 如何强制执行顺序执行

时间:2017-01-05 22:26:55

标签: ruby class refactoring

我有许多必须按顺序完成的任务。在将任务逻辑从方法重构为单独的类之后,我发现它们的性能不再保证是顺序的(即第一个和第三个任务在第一个完成之前开始)。这里发生了什么,我该如何确保顺序性能?

原始代码如下:

class MyClass
  def do_stuff
    do_first_thing
    do_second_thing
    do_third_thing
  end # each waits for its predecessor to finish before starting

  def do_first_thing
    # takes a minute to complete
  end

  def do_second_thing
    # takes a minute to complete
  end

  def do_third_thing
    # takes a minute to complete
  end
end

重构的代码如下所示:

class MyClass
  def do_stuff
    FirstThing.new.do_it
    SecondThing.new.do_it
    ThirdThing.new.do_it
  end # for some reason, each doesn't wait for its predecessor to finish before starting
end

class FirstThing
  def do_it
    # takes a minute to complete
  end
end

class SecondThing
  def do_it
    # takes a minute to complete
  end
end

class ThirdThing
  def do_it
    # takes a minute to complete
  end
end

编辑:没有进行任何线程或并行处理。

编辑:我使用以下代码尝试复制我的问题,它似乎正在工作,所以也许问题出在其他地方。我将在此处发布进度和结果。

#
# OLD VERSION
#

class OldJob
  def work_it
    move_it
    shake_it
    bake_it
  end

  def move_it
    puts "MOVING IT..."
    sleep 5
  end

  def shake_it
    puts "SHAKING IT..."
    sleep 5
  end

  def bake_it
    puts "BAKING IT..."
    sleep 5
  end
end

OldJob.new.work_it

puts "-----------"

#
# NEW VERSION
#

class MoveJob
  def do_it
    puts "MOVING IT..."
    sleep 5
  end
end

class ShakeJob
  def do_it
    puts "SHAKING IT..."
    sleep 5
  end
end

class BakeJob
  def do_it
    puts "BAKING IT..."
    sleep 5
  end
end

class NewJob
  def work_it
    MoveJob.new.do_it
    ShakeJob.new.do_it
    BakeJob.new.do_it
  end
end

NewJob.new.work_it

按预期结果:

ruby  --->> ruby ~/Desktop/my_job.rb 
MOVING IT...
SHAKING IT...
BAKING IT...
-----------
MOVING IT...
SHAKING IT...
BAKING IT...

最终编辑:

所以我急于重构为多个类似的类,我错误地命名了一些类名,导致它们的执行没有发生。因此,依赖类无法访问前一过程的结果,因为它没有发生。有趣的是,我没有看到任何与类名歧义有关的错误,这是根本原因。

我的问题已经解决。请随意删除?/关闭此问题。

1 个答案:

答案 0 :(得分:1)

我认为你的任务是在不同的线程中运行,否则它们会是连续的。

假设它们在不同的线程中运行,您可以使用回调使其顺序。这些在Javascript中更常见,但在Ruby中也是可行的。

定义接受回调的任务的示例

class FirstThing
  def do_it(&callback)
    Thread.new do
      # do stuff
      callback.call
    end
  end
end

然后运行第一个任务,在回调中调用第二个任务:

FirstThing.new.run do
  SecondThing.new.run
end

请注意,您的MyClass#do_stuff方法会立即返回,而不是等待回调完成。如果没有某种阻塞循环,就不可能使异步代码同步。