我正在努力按照我预期的方式处理 Rx 的错误。
当我有一个 Observable(例如,来自点击流)并且发生异常时,我想捕获它但继续。我尝试过的所有解决方案都会捕获错误然后结束 Observable。有没有办法捕获并继续下去?
例如,下面的 Observable 将发出“1”,然后是“Error”,但永远不会发出“3”。
var range = Rx.Observable.range(1,3)
.map(function(i){
if(i === 2){
throw "Error";
} else {
return i;
}
})
.catch(function(e){
return Rx.Observable.return(e)
});
range.subscribe(function(i){
console.log(i)
});
最佳答案
虽然由于 Observable 契约 (OnNext)* (OnCompleted|OnError) 而无法实现您预期的行为,但有一些实用的方法可以通过引入一个热 Observable 来正确解决这个问题。
let hotRange = Rx.Observable.range(1,3).publish();
let safeRange = hotRange
.map(function (i) {
if (i === 2) {
throw "Error";
} else {
return i;
}
})
.retry();
safeRange.subscribe(i => console.log(i));
hotRange.connect();
See the JSBin .你在问题中提到的 range Observable 是一个冷 Observable。它behaves as a movie ,所以如果发生错误,我们重新订阅,我们需要从“电影”的开头开始订阅,即 1 然后是 “Error”。
您可能隐含地假设 Rx.Observable.range(1, 3) 是一个实时 Observable,即“热”。既然不是,我在上面使用 publish() 创建了 hotRange。这样,它将独立于订阅者发出事件。如果我们希望能够在错误后“继续”,我们需要我们的源(“hotRange”)没有错误。这就是为什么 range.map() 不是热门的 Observable。 retry() 将捕获 hotRange.map( ) 上的错误并将其替换为 hotRange.map( )。因为 hotRange 是热的,所以 retry() 的每次执行都会不同,因为它不记得 hotRange 发出的先前值。因此,当 2 导致的错误在重试中被替换为 hotRange.map( ) 时,hotRange 将随后发出 3,并无误地传递了map函数。
关于javascript - RxJS - 捕获并继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30393314/
我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r
我想学习一些关于Continuation的知识,使用callcc方法从一些文章中键入几个示例,但我遇到了错误:NoMethodError:undefinedmethod`callcc'formain:Objectfrom(pry):2:in`'没有文章提到包含延续库。那么如何解决这个问题呢?谢谢编辑:ruby1.9.2p290(2011-07-09修订版32553)[x86_64-linux] 最佳答案 您需要要求“继续”。require'continuation' 关于ruby-继续,
运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我想从rubyrake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调
我有一个像这样的ruby类:require'logger'classTdefdo_somethinglog=Logger.new(STDERR)log.info("Hereisaninfomessage")endend测试脚本行如下:#!/usr/bin/envrubygem"minitest"require'minitest/autorun'require_relative't'classTestMailProcessorClasses当我运行这个测试时,out和err都是空字符串。我看到消息打印在stderr上(在终端上)。有没有办法让Logger和capture_io一起玩得
关于SSHkit-Github它说:Allbackendssupporttheexecute(*args),test(*args)&capture(*args)来自SSHkit-Rubydoc,我明白execute实际上是test的别名?test之间有什么区别?,execute,capture在Capistrano/SSHKit中我应该什么时候使用? 最佳答案 执行只是执行命令。使用非0退出引发错误。测试方法的行为与execute完全相同,但是它返回bool值(true如果命令以0退出,而false否则)。它通常用于控制任务中的流程
我们如何捕获或/和处理ruby中所有未处理的异常?例如,这样做的动机可能是将某种异常记录到不同的文件或发送电子邮件给系统管理。在Java中我们会做Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandlerex);在Node.js中process.on('uncaughtException',function(error){/*code*/});在PHP中register_shutdown_function('errorHandler');functionerrorHandler(){$error=error_