我有两个源可观察对象,我需要在一个源可观察对象发出后立即计算一些数据。我正在尝试使用 combineAll() 运算符,但它仅在每个源可观察对象首次发出时发出一个值。
是否有任何类似于 combineAll() 的运算符在任何源可观察对象首次发出时立即发出?如果不是,最明确的方法是什么?
我尝试过的:
const source1$ = service.getSomeData();
const source2$ = service.getOtherData();
combineLatest(
source1$,
source2$
).pipe(
map([source1Data, source2Data] => {
// this code only gets executed when both observables emits for the first time
return source1Data + source2Data;
})
)
最佳答案
如果我没理解错的话,您需要如下图所示的模式:
stream1$ => ------ 1 ------ 12 -----------------------
stream2$ => ------------------------- 30 -------------
result$ => ------ 1 ------ 12 ------ 42 --------------
如果一个值可用,则发出该值。如果两者都可用,则发出两者的组合,在本例中为简单求和 (12 + 30 = 42);
首先是输入流,为了本示例,我将它们设为主题,因此我们可以手动推送数据:
const stream1$ = new Subject();
const stream2$ = new Subject();
接下来我们将组合输入,首先通过 startWith 运算符进行管道传输。这确保 combineLatest 产生一个立即发出的 observable - 准确地说是 [null, null]。
const combined$ = combineLatest(
stream1$.pipe(startWith(null)),
stream2$.pipe(startWith(null)),
);
现在您有一个始终发出长度为 2 的数组的可观察对象,其中包含您的数据(本例中为数字)和 null 的任意组合,如下图所示:
stream1$ | startWith(NULL) => NULL ----------- 1 ----------- 12 ----------------------------
stream2$ | startWith(NULL) => NULL ---------------------------------------- 30 -------------
combined$ [NULL, NULL] --- [1, NULL] --- [12, NULL] --- [12, 30] -------
最后,您可以检查并将此输出映射为您想要的格式:两个数字的总和(如果两个数字都可用)或第一个可用的值:
const processedCombinations$ = combined$.pipe(
map(([data1, data2]) => {
if (data1 === null) return data2;
if (data2 === null) return data1;
return data1 + data2;
}),
);
结果:
combined$ => [NULL, NULL] --- [1, NULL] --- [12, NULL] --- [12, 30] -------
processedCombinations$ => NULL ----------- 1 ----------- 12 ----------- 42 -------------
仍然存在一个问题:combined$ 发出的第一个值是 [null, null],导致 processedCombinations$ 发出 null 最初。解决此问题的一种方法是使用 skipWhile 将另一个管道链接到 processedCombinations$ 上:
const final$ = processedCombinations$.pipe(skipWhile((input) => input === null));
结果:
combined$ => [NULL, NULL] --- [1, NULL] --- [12, NULL] --- [12, 30] -------
processedCombinations$ => NULL ----------- 1 ----------- 12 ----------- 42 -------------
final$ => ---------------- 1 ----------- 12 ----------- 42 -------------
另一种 - 我觉得更好 - 方法是在 processedCombinations$ (现在实际上是 final$)从它创建之前过滤 combined$ 流:
const combinedFiltered$ = combined$.pipe(
filter(([first, second])=> first !== null || second !== null),
);
const final$ = combinedFiltered$.pipe(
map(([data1, data2]) => {
if (data1 === null) return data2;
if (data2 === null) return data1;
return data1 + data2;
}),
);
相应的图表很好地显示了如何尽可能早地在流层次结构中消除不相关的值:
combined$ => [NULL, NULL] --- [1, NULL] --- [12, NULL] --- [12, 30] -------
combinedFiltered$ => ---------------- [1, NULL] --- [12, NULL] --- [12, 30] -------
final$ => ---------------- 1 ----------- 12 ----------- 42 -------------
上面的图表可以用这段代码生成:
final$.subscribe(console.log);
stream1$.next(1);
// logs: 1
stream1$.next(12);
// logs: 12
stream2$.next(30);
// logs: 42
使用的进口:
import { combineLatest, Subject } from 'rxjs';
import { filter, map, skipWhile, startWith } from 'rxjs/operators';
关于javascript - RxJS combineLatest 无需等待源可观察量发出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54039425/
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
是否可以在PyYAML或Ruby的Psych引擎中禁用创建anchor和引用(并有效地显式列出冗余数据)?也许我在网上搜索时遗漏了一些东西,但在Psych中似乎没有太多可用的选项,而且我也无法确定PyYAML是否允许这样做.基本原理是我必须序列化一些数据并将其以可读的形式传递给一个不是真正的技术同事进行手动验证。有些数据是多余的,但我需要以最明确的方式列出它们以提高可读性(anchor和引用是提高效率的好概念,但不是人类可读性)。Ruby和Python是我选择的工具,但如果有其他一些相当简单的方法来“展开”YAML文档,它可能就可以了。 最佳答案
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan
我有一个包含100多个zip文件的目录,我需要读取zip文件中的文件以进行一些数据处理,而无需解压缩存档。是否有一个Ruby库可以在不解压缩文件的情况下读取zip存档中的文件内容?使用rubyzip报错:require'zip'Zip::File.open('my_zip.zip')do|zip_file|#Handleentriesonebyonezip_file.eachdo|entry|#Extracttofile/directory/symlinkputs"Extracting#{entry.name}"entry.extract('here')#Readintomemoryc
有什么显着的区别吗sleep10和wait_until(10)他们似乎都在做同样的事情:WAITING10秒,然后继续下一步 最佳答案 sleep在指定时间内什么都不做。wait_untiltakesablock.它一直等到block评估为真或超时。如果没有给出block,它们的行为相同。 关于ruby-Watir...sleep和等待之间的区别,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/que
我需要动态创建一个Ruby类,即动态地从ActiveRecord::Base派生。我暂时使用eval:eval%Q{class::#{klass}是否有一种等效的、至少同样简洁的方法可以在不使用eval的情况下执行此操作? 最佳答案 您可以使用Class类,其中的类是实例。困惑了吗?;)cls=Class.new(ActiveRecord::Base)doself.table_name=table_nameendcls.new 关于ruby-无需eval即时创建Ruby类,我们在Stac
我读过的关于Ruby符号的每一篇文章都在谈论符号相对于字符串的效率。但是,这不是1970年代。我的电脑可以处理一些额外的垃圾收集。我错了吗?我拥有最新最好的奔腾双核处理器和4GBRAM。我认为这应该足以处理一些字符串。 最佳答案 您的计算机可能能够处理“一点点额外的垃圾收集”,但是当“一点点”发生在运行数百万次的内部循环中时呢?如果它在内存有限的嵌入式系统上运行呢?有很多地方你可以随意使用字符串,但在某些地方你不能。这完全取决于上下文。 关于ruby-现代计算机的功能是否不足以处理字符串
我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文