如何在没有嵌套订阅的情况下订阅命令执行信号的完成?

Pau*_*ung 5 objective-c frp reactive-cocoa

我尝试了以下但没有成功.等效使用-subscribeNext:按预期工作.

// A
[[_viewModel.loginCommand.executionSignals flatten] subscribeCompleted:^{
    NSLog(@"A");
}];
Run Code Online (Sandbox Code Playgroud)

我唯一的工作实现如下:

// B
[_viewModel.loginCommand.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    [loginSignal subscribeCompleted:^{
        NSLog(@"B");
    }];
}];
Run Code Online (Sandbox Code Playgroud)

为什么不能-flatten在"A"中工作,如何重写"B"以不使用嵌套订阅?

Dav*_*Lee 10

-flatten运算符返回当所有的内信号的已完成,只有完成了一个信号,这需要外部信号来完成为好.同样如此-concat.因此,一旦您应用任一运算符,结果信号就不会表示单个完成,只有最终的汇总完成.

替代嵌套订阅,您可以转换内部信号,以便它们发送表示完成的值.一种方法是-materialize:

[[[_viewModel.loginCommand.executionSignals
    map:^(RACSignal *loginSignal) {
        // Using -ignoreValues ensures only the completion event is sent.
        return [[loginSignal ignoreValues] materialize];
    }]
    concat]
    subscribeNext:^(RACEvent *event) {
        NSLog(@"Completed: %@", event);
    }];
Run Code Online (Sandbox Code Playgroud)

请注意,我使用-concat而不是-flatten,因为它匹配RACCommand默认串行执行的语义.在这种情况下,它们最终会做同样的事情,因为命令只能一次执行一个信号-flatten,-concat所以会退化.

使用-materialize不是执行此操作的唯一方法,它恰好发送一个表示完成的值,但这可能是您发现对您的用例具有适当重要性的任何值.

  • 这是非常常见的操作 - 显示操作成功的确认.例如,我想发布一条消息,我希望看到操作失败或完成.真的没有办法更清楚地做到这一点吗?我的意思是,这种方法仍然只是对嵌套的executionSignal的订阅.例如,如果命令有多个执行信号怎么办? (2认同)
  • `RACCommand`的`executionSignals`不直接暴露完成事件.如果您不想使用`materialize`,另一种选择是使用有意义的值来记录"成功完成".如果信号没有发送任何值,那么您可以发送任何值来表示完成,然后忽略它.是的另一种选择是使用`doCompleted:`运算符作为嵌套订阅的替代方法. (2认同)
  • 因此,基本上RACCommand不用于跟踪操作是否失败或成功,它只是跟踪操作何时执行以及何时不执行.我做对了吗? (2认同)
  • 不完全的.您可以跟踪错误,可以跟踪值/结果,甚至可以跟踪完成情况,但不幸的是只能间接/非惯用.它的典型/主要目的是防止某种类型的并发操作,而只是让某些事情发生在一起.为了使其更强大,它会显示一个信号,指示动作是否可以开始.所有这些都有助于UI. (2认同)