- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有 2 个嵌套的 Observable Streams,它们执行 HTTP 请求。现在我想显示加载指示器,但无法使其正常工作。
var pageStream = Rx.createObservableFunction(_self, 'nextPage')
.startWith(1)
.do(function(pageNumber) {
pendingRequests++;
})
.concatMap(function(pageNumber) {
return MyHTTPService.getPage(pageNumber);
})
.do(function(response) {
pendingRequests--;
});
Rx.createObservableFunction(_self, 'search')
.flatMapLatest(function(e) {
return pageStream;
})
.subscribe();
search();
nextPage(2);
nextPage(3);
search();
这将触发 pendingRequests++
4 次,但 pendingRequests--
只会触发一次,因为 flatMapLatest
会在前 3 个 HTTP 之前取消内部 observable响应到达。
我找不到类似 onCancel
回调的任何东西。我还尝试了 onCompleted
和 onError
,但它们也不会被 flatMapLatest
触发。
还有其他方法可以实现吗?
谢谢!
示例:单个 search()
调用。
示例:search()
和 nextPage()
调用。 (在 search() 响应返回之前调用了 nextPage()。)
示例:search()
、search()
。 (search() 调用相互覆盖,尽管第一个调用的响应可以被忽略)
示例:search()
、nextPage()
、search()
。 (再说一遍:因为第二次search(),前面search()和nextPage()的响应可以忽略)
示例:search()
、nextPage()
。但是这次 nextPage() 是在 search() 响应返回后调用的。
我尝试使用pendingRequests
计数器,因为我可以同时有多个相关 请求(例如:search()、nextPage()、nextPage ()
)。然后,当然我想在所有相关请求完成后禁用加载指示器。
调用search()、search()
时,第一个search()是无关紧要的。这同样适用于 search()、nextPage()、search()
。在这两种情况下,只有一个事件的相关请求(最后一个 search()
)。
最佳答案
使用 switchMap
又名 flatMapLatest
,您希望在新的外部项到达时尽快 trim 当前内部流的执行。这无疑是一个很好的设计决定,否则它会带来很多困惑并允许一些诡异的 Action 。如果你真的想做一些事情 onCancel
你总是可以使用自定义 unsubscribe
回调创建你自己的可观察对象。但我仍然建议不要将 unsubscribe
与外部上下文的状态更改结合起来。理想情况下,unsubscribe
只会清理内部使用的资源。
然而,您的特殊情况可以在不访问 onCancel
或类似方法的情况下得到解决。关键观察是 - 如果我正确理解您的用例 - 在 search
上所有以前/未决的操作可能会被忽略。因此,不用担心递减计数器,我们可以简单地从 1 开始计数。
关于片段的一些评论:
BehaviorSubject
来计算未决请求 - 因为它已准备好与其他流组合;search
仍未决时是否允许 nextPage
- 但似乎只是使用 concatMapTo
的问题vs merge
;Rx
运算符。console.clear();
const searchSub = new Rx.Subject(); // trigger search
const nextPageSub = new Rx.Subject(); // triger nextPage
const pendingSub = new Rx.BehaviorSubject(); // counts number of pending requests
const randDurationFactory = min => max => () => Math.random() * (max - min) + min;
const randDuration = randDurationFactory(250)(750);
const addToPending = n => () => pendingSub.next(pendingSub.value + n);
const inc = addToPending(1);
const dec = addToPending(-1);
const fakeSearch = (x) => Rx.Observable.of(x)
.do(() => console.log(`SEARCH-START: ${x}`))
.flatMap(() =>
Rx.Observable.timer(randDuration())
.do(() => console.log(`SEARCH-SUCCESS: ${x}`)))
const fakeNextPage = (x) => Rx.Observable.of(x)
.do(() => console.log(`NEXT-PAGE-START: ${x}`))
.flatMap(() =>
Rx.Observable.timer(randDuration())
.do(() => console.log(`NEXT-PAGE-SUCCESS: ${x}`)))
// subscribes
searchSub
.do(() => console.warn('NEW_SEARCH'))
.do(() => pendingSub.next(1)) // new search -- ingore current state
.switchMap(
(x) => fakeSearch(x)
.do(dec) // search ended
.concatMapTo(nextPageSub // if you wanted to block nextPage when search still pending
// .merge(nextPageSub // if you wanted to allow nextPage when search still pending
.do(inc) // nexpage started
.flatMap(fakeNextPage) // optionally switchMap
.do(dec) // nextpage ended
)
).subscribe();
pendingSub
.filter(x => x !== undefined) // behavior-value initially not defined
.subscribe(n => console.log('PENDING-REQUESTS', n))
// TEST
const test = () => {
searchSub.next('s1');
nextPageSub.next('p1');
nextPageSub.next('p2');
setTimeout(() => searchSub.next('s2'), 200)
}
// test();
// FUZZY-TEST
const COUNTER_MAX = 50;
const randInterval = randDurationFactory(10)(350);
let counter = 0;
const fuzzyTest = () => {
if (counter % 10 === 0) {
searchSub.next('s' + counter++)
}
nextPageSub.next('p' + counter++);
if (counter < COUNTER_MAX) setTimeout(fuzzyTest, randInterval());
}
fuzzyTest()
<script src="https://npmcdn.com/rxjs@5.0.0-beta.11/bundles/Rx.umd.js"></script>
关于javascript - RxJs flatMapLatest/switchMap 取消回调。 onCancel() 在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39236361/
我在 Android Studio 中使用 AsyncTask 在后台使用 TCP 连接。然后我在 PreExecute 中有一个运行器,它以 5 秒的超时时间执行一个运行器,然后在 AsyncTas
在我的主 Activity 的 onCreate() 方法中,我设置了一个回调到 Activity 的 onCancel() 方法,当搜索对话框被用户取消而不发出搜索时调用(我相信)。这是我的注册码:
我正在编写一个 Android 应用,目前正在尝试从 Firebase 数据库中读取数据。我遵循文档 here关于如何阅读。现在,在调用 OnCancelled 的情况下(意味着 Firebase 读
我的应用程序中的 facebook 身份验证有时会调用 onCancel 方法,我不知道发生了什么。我觉得我的代码是正确的,有时 auth 工作得很好,有时却不行。 我的授权源代码:https://g
在 2.3.6 设备上运行的 Android SDK v15。 我遇到一个问题,当我在 doInBackground() 中调用 cancel() 时,仍然调用 onPostExecute()打电话。
我应该在我的 grpc 服务器处理的每个调用的开始和结束时执行一些代码。 我使用 ServerCall.Listener: 调用开始时执行的代码位于监听器的构造函数中 在调用结束时执行的代码由 onC
当使用 ckeditor 链接、图像和表格属性对话框时,如果用户单击取消,CKEDITOR 将检查是否有任何更改,如果更改,则使用 js 确认弹出窗口提示用户。 如何在取消时禁用此提示;我们的 web
我使用 Azure DevOps 在 Azure Batch AI 上安排作业。启 Action 业效果很好,我有同样的 python 代码。 我想要实现的是,当取消构建时,Batch AI 实验中的
我使用 Azure DevOps 在 Azure Batch AI 上安排作业。启 Action 业效果很好,我有同样的 python 代码。 我想要实现的是,当取消构建时,Batch AI 实验中的
我有一个AsyncTask它调用 Web 服务并从中获取 json 对象。我想为此任务设置一个超时,以便如果出现任何问题(例如互联网连接断开等),AsyncTask 就会被取消。这是到目前为止我的代码
我有一个 Activity 将它启动的任何 AsyncTask 添加到 vector 列表。 当 Activity 被销毁时,它会遍历 vector 列表并在所有 AsyncTasks 上调用 onC
我实现了一个Loader,在onStopLoader() 中,我调用了cancelLoad() 方法。然而,尽管有上述调用,onCanceled() 没有被调用。这个回调的目的是什么? 在我的 Act
我在 AsyncTask 的 OnCancelled() 方法中发现错误,错误如下: Exception of type 'Java.Lang.IllegalArgumentException' wa
我在代码中添加了 Facebook 登录按钮。效果很好。 假设用户通过facebook登录并取消选中“user_friends”权限:将调用“onSuccess”函数,以便可以从loginResult
我使用 firebase 发现并发出 firebase 不发送超时错误或无法连接到服务器的问题。在这种情况下,我们无法向用户提供问题所在的正确信息。 Firebase 开发人员必须处理这个非常常见的用
在我的应用程序中,我只是尝试通过在以下代码中添加 ListenerForSingleValueEvent 从我的 Firebase 数据库中检索阅读文章: myRef.child("passages"
尝试使用 dialog fragment 的后退按钮时 我很好奇使用 onBackPressed() 之间的区别(或 onBackPressedCallBack)和 onCancel() . 我试图定
我正在通过 facebook 实现登录并使用 SDK 4.1.0 获取用户电子邮件 ID,如 facebook documentation 所示。但出现的问题是,每次在 onActivityResul
根据 AsyncTask.cancel method 的 Android 引用, onCancelled() 和 doInBackground() 之间的时间是明确定义的: Calling this
我有 2 个嵌套的 Observable Streams,它们执行 HTTP 请求。现在我想显示加载指示器,但无法使其正常工作。 var pageStream = Rx.createObservabl
我是一名优秀的程序员,十分优秀!