improved API to look like RxJava, returning observable