如何中止@cycle/http 驱动程序发出的调用?
How to abort calls made by @cycle/http driver?
我对整个 Cycle.js/RxJS 生态系统还很陌生,希望有人能指导我如何中止自 it looks like doable somehow 以来正在进行的 ajax 通话。
如果能从 search-github-user 派生出一个小例子就太棒了。
为了避免 SO 狂热者否决投票,我在此处添加了该示例的副本:
import Cycle from '@cycle/core';
import {Observable} from 'rx';
import {div, label, input, hr, ul, li, a, makeDOMDriver} from '@cycle/dom';
import {makeHTTPDriver} from '@cycle/http';
function main(sources) {
// Requests for Github repositories happen when the input field changes,
// debounced by 500ms, ignoring empty input field.
const searchRequest$ = sources.DOM.select('.field').events('input')
.debounce(500)
.map(ev => ev.target.value)
.filter(query => query.length > 0)
.map(q => ({
url: 'https://api.github.com/search/repositories?q=' + encodeURI(q),
category: 'github',
}));
// Requests unrelated to the Github search. This is to demonstrate
// how filtering for the HTTP response category is necessary.
const otherRequest$ = Observable.interval(1000).take(2)
.map(() => 'http://www.google.com');
// Convert the stream of HTTP responses to virtual DOM elements.
const vtree$ = sources.HTTP
.filter(res$ => res$.request.category === 'github')
.flatMap(x => x)
.map(res => res.body.items)
.startWith([])
.map(results =>
div([
label({className: 'label'}, 'Search:'),
input({className: 'field', attributes: {type: 'text'}}),
hr(),
ul({className: 'search-results'}, results.map(result =>
li({className: 'search-result'}, [
a({href: result.html_url}, result.name)
])
))
])
);
const request$ = searchRequest$.merge(otherRequest$);
return {
DOM: vtree$,
HTTP: request$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
HTTP: makeHTTPDriver()
});
更新
感谢@user3743222 指出master 分支的改动,貌似作者发布了新版本,现在中止的部分是here.
我完全不熟悉新代码,但在旧代码中,http 驱动程序 returns 似乎是每个请求的可观察对象。如果该可观察对象 terminates/is 在请求完成之前取消订阅,则该请求将被中止。所以基本上,调用 API,获取封装请求结果的可观察对象,并在您想要中止时终止该可观察对象。
如何随意终止一个observable?你可能会使用
takeUntil(someOtherStream)
如果您有另一个流信号中止。
在当前版本中,所有 response$
流都会立即被监听,因此它们永远不会在请求到来之前终止,并且中止不会有效地工作。上面有一个issue。
我对整个 Cycle.js/RxJS 生态系统还很陌生,希望有人能指导我如何中止自 it looks like doable somehow 以来正在进行的 ajax 通话。
如果能从 search-github-user 派生出一个小例子就太棒了。
为了避免 SO 狂热者否决投票,我在此处添加了该示例的副本:
import Cycle from '@cycle/core';
import {Observable} from 'rx';
import {div, label, input, hr, ul, li, a, makeDOMDriver} from '@cycle/dom';
import {makeHTTPDriver} from '@cycle/http';
function main(sources) {
// Requests for Github repositories happen when the input field changes,
// debounced by 500ms, ignoring empty input field.
const searchRequest$ = sources.DOM.select('.field').events('input')
.debounce(500)
.map(ev => ev.target.value)
.filter(query => query.length > 0)
.map(q => ({
url: 'https://api.github.com/search/repositories?q=' + encodeURI(q),
category: 'github',
}));
// Requests unrelated to the Github search. This is to demonstrate
// how filtering for the HTTP response category is necessary.
const otherRequest$ = Observable.interval(1000).take(2)
.map(() => 'http://www.google.com');
// Convert the stream of HTTP responses to virtual DOM elements.
const vtree$ = sources.HTTP
.filter(res$ => res$.request.category === 'github')
.flatMap(x => x)
.map(res => res.body.items)
.startWith([])
.map(results =>
div([
label({className: 'label'}, 'Search:'),
input({className: 'field', attributes: {type: 'text'}}),
hr(),
ul({className: 'search-results'}, results.map(result =>
li({className: 'search-result'}, [
a({href: result.html_url}, result.name)
])
))
])
);
const request$ = searchRequest$.merge(otherRequest$);
return {
DOM: vtree$,
HTTP: request$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
HTTP: makeHTTPDriver()
});
更新
感谢@user3743222 指出master 分支的改动,貌似作者发布了新版本,现在中止的部分是here.
我完全不熟悉新代码,但在旧代码中,http 驱动程序 returns 似乎是每个请求的可观察对象。如果该可观察对象 terminates/is 在请求完成之前取消订阅,则该请求将被中止。所以基本上,调用 API,获取封装请求结果的可观察对象,并在您想要中止时终止该可观察对象。
如何随意终止一个observable?你可能会使用
takeUntil(someOtherStream)
如果您有另一个流信号中止。
在当前版本中,所有 response$
流都会立即被监听,因此它们永远不会在请求到来之前终止,并且中止不会有效地工作。上面有一个issue。