doFinally 是否在 Reactor 中的同一个线程上执行

Does doFinally execute on the same thread in Reactor

doFinally 是否在同一个线程上执行?下面的代码会阻塞主线程吗?

mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
    FileUtils.cleanDirectory(folderName); // this method is blocking
});

如果是这样,在 doFinally 的单独线程中执行 cleanDirectory 的最佳方法是什么?

将阻塞调用包装在 Runnable 中,运行 包装在单独的 thread 中:

Runnable task = () -> {FileUtils.cleanDirectory(folderName)};

Mono<Object> cleanDirPromise = Mono.fromRunnable(task);

mono
.map(fileName -> asyncDownloadFile(fileName, folderName))
.doFinally(v -> {
    cleanDirPromise.subscribeOn(Schedulers.parallel()).subscribe();
});

注意:这实际上是一个 fire-and-forget 调用,您不会真正关心 cleanDirPromise 的结果。

为此,最好使用 .then() 运算符:

mono
    .map(fileName -> asyncDownloadFile(fileName, folderName))
    .then()
    .flatMap(
        Mono.fromRunnable(() -> FileUtils.cleanDirectory(folderName))
            .subscribeOn(Schedulers.boundedElastic())
    )
    ...

运算符 then() 保证 cleanDirectory 将在 asyncDownloadFile 之后执行,还允许您构建一个管道并处理错误。