除了 System.currentTimeMillis() 之外,使用 .defer() 的一个很好的用例是什么



我有以下代码:

Single<Player> createPlayerSingle() {
    Integer playerId = Random.nextInteger();
    return playersDao.createSingle(id);
}

有人告诉我应该添加Single.defer().

Single<Player> createPlayerSingle() {
    return Single.defer(() -> {
        Integer playerId = Random.nextInteger();
        return playersDao.createSingle(id);
    }
}

这个想法是,如果我们为createPlayerSingle()创建另一个订阅,我们将不会生成新的 id(基本上我们会重用旧的 id(。

我不明白为什么会这样。那么我们是否应该向以一些同步代码块开头的每个函数添加defer

Single<T> methodSingle() {
    return Single.defer(() -> {
        Integer id = Random.nextInteger(); // sync block of code
        ....
        return dao.createSingle(id);
    });
}

我确实了解defer的作用(它为每个订阅者执行 lambda,例如,如果我们System.currentTimeMillis()放入 lambda 中,我们将为 2 个订阅收到 2 个不同的值,而不是 1 个相同的值,如果我们使用 .just.fromCallable 而不是 .defer(。

当我们从争论中获取属性时,我们也应该在这里defer吗?这对我来说没有意义(即使我们第二次订阅该方法的结果,我们也会在用一些参数调用它(。

Single<T> methodSingle(Object object) {
        return Single.defer(() -> {
            Integer id = object.id; // sync block of code
            ....
            return dao.createSingleFrom(id);
        });
    }

当你编写一个返回Single(或任何其他 RxJava 流类型(的方法时,你返回的东西可以多次订阅,可能同时订阅。

Defer是一个非常强大(但简单(的运算符,允许您定义每个订阅的状态。例如,如果您希望第一次排放具有特殊行为:

Observable<Integer> numbers = Observable.just(1, 2, 3);
Observable<Integer> numbers2 = 
    Observable.defer(() -> {
        boolean[] first = new boolean[] {true};
        return numbers.doOnNext(x -> {
            if (first[0]) {
                System.out.println("first=" + x);
                first[0] = false;
            } else {
                System.out.println(x);
            }
        });
    });
numbers2.subscribe();
numbers2.subscribe();

生产

first=1
2
3
first=1
2
3

重新执行此代码:

Single<T> methodSingle(Object object) {
    return Single.defer(() -> {
        Integer id = object.id; // sync block of code
        ....
        return dao.createSingleFrom(id);
    });
}

如果object是不可变的,那么这是没有意义的,你可以像你怀疑的那样省略defer

每次我觉得有必要弄乱 .create(( 时,我意识到使用 .defer(( 很简单。.defer(( prep 代码通常是启动查询并将结果推入 Observable.just(( 的代码。

最新更新