我循环了很多项目,我想定期中断循环以保存并在以后继续这样:
begin
big_list.each do |i|
# sensitive stuff
sensitive_method(i)
# other sensitive stuff
end
rescue Interrupt
# finish the current iteration
# then do something else (save)
# don't raise (print done)
end
敏感我的意思是,如果在迭代过程中引发Interrupt
,数据将被破坏,所以我需要保证迭代在退出之前完成。
另外,如果引发了另一个异常,它仍然应该完成循环,但之后将其提升
在测试场景中使用mudasobwa的答案:
while true
result = begin
puts "start"
sleep 1
puts "halfway"
sleep 1
puts "done\n\n"
nil
rescue Exception => e
e
end
case result
when Interrupt
puts "STOPPED"
break
when Exception then raise result
end
end
我明白了:
start
halfway
done
start
^C: /...
STOPPED
这是我的确切问题,我需要它来完成循环(睡眠,中途打印,睡眠,打印完成)然后才会爆发(包裹掉,睡觉......在方法中没有帮助)
答案 0 :(得分:2)
TL; DR:无法从中间内部继续执行该方法。
$('input.sortInp').change(function () {
var input = $(this);
input.parents('.float_left').find('.sortLoaderDiv').html('<img
class="sortLoader" src="/images/icons/loading_small1.gif">');
setTimeout(function () {
input.parents('.float_left').find('.sortLoaderDiv').html("Some text");
}, 1000);
});
旁注:你可能不想拯救最顶层的big_list.each do |i|
# sensitive stuff
result = begin
sensitive_method(i)
nil
rescue Exception => e
e
end
# other sensitive stuff
case result
when Interrupt
puts "done"
break "done"
when Exception then raise result
end
end
,但有些子类对救援有意义。
为了完成大部分操作:
Exception
答案 1 :(得分:2)
在主线程中引发了Interrupt异常。如果您使用辅助线程来处理列表,它将永远不会被中断。您将需要一种方法来告诉工作线程终止。在主线程中抢救中断并设置一个由孩子检查的标志就可以完成。
BigList = (1..100)
def sensitive_method(item)
puts "start #{item}"
sleep 1
puts "halfway #{item}"
sleep 1
puts "done #{item}"
puts
end
@done = false
thread = Thread.new do
begin
BigList.each do |item|
break if @done
sensitive_method item
end
end
end
begin
thread.join
rescue Interrupt
@done = true
thread.join
end
答案 2 :(得分:0)
在rescue子句中使用的关键字ensure
可用于此类情况,其中必须在发生异常后执行代码。
[-1, 0, 1].each do |i|
begin
puts "i=#{i} before exception"
# <additional code>
n = 1/i
rescue ZeroDivisionError => e
puts "Exception: #{e}"
exit
ensure
puts "Just executed 1/#{i}"
# <additional code>
end
end
i=-1 before exception
Just executed 1/-1
i=0 before exception
Exception: divided by 0
Just executed 1/0
请注意,begin/rescue/ensure/end
必须位于循环内,并且ensure
之后的代码将针对每个i
执行,无论是否发生零分割异常。