代码之家  ›  专栏  ›  技术社区  ›  Garfield

从控制器动态更改视图-在Rails中带线程的进度条

  •  1
  • Garfield  · 技术社区  · 14 年前

    我有一个在我的控制器中花费时间的任务,我想在我的视图中触发一个简单的进度条/进度状态。

    在我的控制器里我有一些

    threads = []
    total.times do |x|
        Thread.new {
            the_time_taking_task(x)
            #Something here to trigger the progressbar in the view
        }
    end
    
    threads.each { |aThread|  aThread.join }
    render :action => 'some_action'    
    

    我不能在其中放置渲染,因为它会引发双重渲染错误。 我试着做个渲染然后回到那里 return can't jump across threads 误差

    我正在尝试渲染,因为它似乎是我的控制器与视图对话的唯一方式。我的方法不对吗?

    希望在视图中使用类似这样的简单方法,通过该调用应用进度条宽度

    <div style="width: <%= (percent_val)%>px; ">
    

    请教。

    2 回复  |  直到 14 年前
        1
  •  6
  •   shingara    14 年前

    是的,这是一个错误的方法。

    Web是无状态的,您不能阻塞一个进程来呈现视图,然后通过另一个请求获取它。

    好办法是:

    1)生成队列任务而不是线程。您可以使用延迟的_job、resque或queue系统,如rabbitmq或beanstacked

    2)添加一个控制器来检查队列中的进程是否结束以及进度如何。在内部,您放入队列ID并检查是否结束,然后返回进度百分比。

    最简单的方法是使用Ajax。

        2
  •  2
  •   Aaron Qian    14 年前

    是的,你的方法是错误的。

    辛加拉解释得很好。

    我为您提供了一个更具体的解决方案。

    要获得您想要的效果,您基本上需要以下步骤:

    1. 将线程卸载到后台作业服务器。结帐 resque delayed_job .
    2. 让后台作业将进度写入数据库或某个持久介质。
    3. 在Rails中,编写一个返回当前进度的操作(如JSON或XML)
    4. 在您的视图中,编写一个定期的Ajax请求,调用步骤3中编写的操作。
    5. 相应地更新视图。

    你完了!D