1. fromCallable() & defer() 介绍

fromCallable() 和 defer()都是可以延迟执行直到有订阅者订阅。

不同点是defer()是无状态的,针对每次订阅,即如果我们放 System.currentTimeMillis() 到 lambda表达式中,我们将得到两个不同的值。 如果有两次订阅,使用.fromCallable 或者 .just ,那么将只有一个相同的值。

2. andThen()

Completable.andThen() 被用作连续执行, 但是andThen()中的lambda表达式也有执行时机的不同。

(1)例:


class User {String name;
}
private User mUser; // this is a global variablepublic Observable<String> stringObservable() {return Completable.fromAction(() -> {mUser = new User();mUser.name = "name";}).andThen(Observable.just(mUser.name));
}

首先,我在Completable.fromAction中做了一些初始化,我希望andThen运算符只在完成Completable.fromAction后启动.

这意味着我希望在andThen运算符启动时初始化mUser.

订阅后得到如下错误:

问题出在使用Observable.just(mUser.name)语句. just运算符将尝试立即创建observable,虽然它只会在Completable.fromAction之后发出.于是使用just创建Observable时,mUser为null.

应该使用如下代码替代:


andThen(Observable.defer(() -> Observable.just(mUser.name)));andThen(Observable.fromCallable(() -> mUser.name));

(2)真实问题:

问题代码:

return Single.fromCallable(() -> newBalanceRegister).flatMap(register -> populateOperationNumbers(model, register).andThen(Single.fromCallable(() -> {final Optional<Long> maxRegisterOperationNumber = register.getOperations().stream().map(BalanceRegisterOperation::getNumber).max(Long::compareTo);if (maxRegisterOperationNumber.isPresent() && shouldUpdateRegisterNumber(register,maxRegisterOperationNumber.get())) {register.setNumber(maxRegisterOperationNumber.get());}return register;}))).flatMap(register -> sourceToDistributeService.applySources(register).andThen(proceedWithBBREvents(register)));

问题出在最后一行:proceedWithBBREvents会立即创建Single导致了event 没有发送, 因为 allocation 还没有完成。

解决方案

return populateOperationNumbers(model, newBalanceRegister).andThen(Completable.defer(() -> {final Optional<Long> maxRegisterOperationNumber = newBalanceRegister.getOperations().stream().map(BalanceRegisterOperation::getNumber).max(Long::compareTo);if (maxRegisterOperationNumber.isPresent() && shouldUpdateRegisterNumber(newBalanceRegister,maxRegisterOperationNumber.get())) {newBalanceRegister.setNumber(maxRegisterOperationNumber.get());}return sourceToDistributeService.applySources(newBalanceRegister);})).andThen(Completable.defer(() -> proceedWithBBREvents(newBalanceRegister))).andThen(Single.fromCallable(() -> newBalanceRegister));

修正了RxJava的使用方法和顺序,现在可以正确的订阅事件了。

该笔记取自同事Zijie,请勿转载。

fromCallable() defer() andThen()相关推荐

  1. Go 学习笔记(17)— 函数(03)[defer 定义、defer 特点、defer 释放资源]

    1. defer 定义 Go 函数的关键字 defer 可以提供注册多个延迟调用,只能出现在函数内部,在 defer 归属的函数即将返回时,将延迟处理的语句按 defer 的逆序进行执行,这些调用遵循 ...

  2. Go基础编程:延迟调用defer

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 本篇文章所讲的就是go编程中的延迟调用defer,希望对社区的成员有较多的帮助. 1 defer作用 关键字defer ...

  3. js的defer属性

    js的defer属性说明:<script src="js.js" type="text/javascript defer="defer"/> ...

  4. golang源码分析:defer流程分析

    defer defer是golang中使用的延迟调用的函数,该函数的使用场景就是如果函数执行出错(panic),也能够通过recover方式进行捕捉错误并将出错时的一些资源进行回收,如果在性能有要求的 ...

  5. Script标签的async和defer

    之前有写过HTML页面渲染过程,知道了JavaScript是会阻塞DOM解析的,所以我们会把script标签放到底部防止阻塞HTML解析.其实script还有两个属性,async和defer,也是可以 ...

  6. prefetch 和preload_前端preload, prefetch,dns-prefetch,defer,async了解一下

    preload 通过rel="preload"进行内容预加载 元素的 rel 属性的属性值preload能够让你在你的HTML页面中 元素内部书写一些声明式的资源获取请求,可以指明 ...

  7. GO语言教程4:defer(延迟语句)详解

    文章目录 1.defer语句格式 2.defer执行的时间 3.defer语句的作用 4.defer语句执行的顺序 5.defer与return的value之间的关系 6.用defer进行代码跟踪 7 ...

  8. script标签的defer属性

    defer 属性规定是否对脚本执行进行延迟,直到页面加载为止. 有的 javascript 脚本 document.write 方法来创建当前的文档内容,其他脚本就不一定是了. 如果您的脚本不会改变文 ...

  9. Go笔记-错误处理和defer

    为什么80%的码农都做不了架构师?>>> error error类型的声明可在builtin包中查看: type error interface {Error() string } ...

最新文章

  1. VMware虚拟机安装黑苹果MacOS Mojave系统详细教程
  2. openstack-swift云存储部署(一)
  3. MSP430F5529 DriverLib 库函数学习笔记(四点五)printf打印输出
  4. 商业项目中代码质量是否重要?
  5. python网络爬虫系列(四)——requests模块
  6. python jsonpath效率低_Python学习:jsonpath的性能问题
  7. Memcached命令-存储命令-查找命令-清理命令
  8. 还花几个小时整理线缆你就OUT了,VR自由漫步来了
  9. 259年后,中国最大的皇家园林上云了
  10. 浏览器大战之谷歌浏览器的逆袭
  11. R2V软件自动矢量化----体验篇
  12. oracle11g批量insert多条,Oracle高效批量插入数据
  13. npm create vite@latest 失败
  14. java dns缓存清理_清除DNS缓存信息方法
  15. 11月面完美团+网易+腾讯+百度+滴滴熬夜5天整理面经攒人品
  16. unity EZ Replay Manager 1.53
  17. 统计Textarea中字数的方法
  18. 使用python删除一个文件或文件夹
  19. 数据分析行业薪资的秘密,你想知道的都在这里(1)
  20. 计算机网络课程设计报告 计算校验和 湖南文理学院,湖南文理学院课程设计 计算机网络实验室综合布线系统的设计与测试...

热门文章

  1. 自动化立体仓库的好处
  2. Final Cut Pro 中文基础教程(四六)画面比例的基本认识
  3. python随机生成密码字符串_Python随机生成带特殊字符的密码
  4. Java 接口概述(interface)
  5. tauri 跨域和响应try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary`解决办法
  6. 强力推荐一个学习coding的网站,怒赞!!
  7. 照相馆预约系统-哪家好?
  8. 十大机器学习算法的一个小总结
  9. 为什么Cocos2D开源引擎最适合游戏创业团队?
  10. Java基础(抽象类和接口)