我正在谈论一些涉及分页的RESTful搜索端点。用户在搜索字段中键入时会触发查询,因此会生成一个带有N个值的Observable,对应于N个结果页面。
代码看起来有点像:
function runQueries(queryObservable) {
return queryObservable
.debounceTime(500)
.distinctUntilChanged()
.switchMap(search);
}
function search(query) {
return Observable.create(observer => searchInto(observer, query, 0));
}
function searchInto(observer, query, start) {
runQuery(query, start).subscribe(result => {
observer.next(result);
if (hasMorePages(result)) {
searchInto(observer, query, start + 1);
} else {
observer.complete();
}
});
}
现在,搜索请求可能需要一段时间,如果用户更改了查询,我也不想检索所有页面。
让我们说搜索返回3页,用户在加载一页后更改查询。我希望看到类似的东西:
USER: types query A
CODE: loads page A1
USER: types query B
CODE: loads page B1
CODE: loads page B2
CODE: loads page B3
switchMap
完成了一半的工作。得到的可观测量具有正确的序列:A1,B1,B2,B3。大。
然而,在幕后我的递归搜索仍在运行所有查询,给服务器,网络等带来不必要的负担。switchMap
确实丢弃了#34;过时的"结果,但它不会阻止递归函数完成其工作。换句话说,它看起来像:
USER: types query A
CODE: loads page A1 -> returned by search observable
USER: types query B
CODE: loads page A2 -> discarded by search observable
CODE: loads page B1 -> returned by search observable
CODE: loads page B2 -> returned by search observable
CODE: loads page A3 -> discarded by search observable
CODE: loads page B3 -> returned by search observable
" A"的顺序和" B"是随机的(受竞争条件限制),但并不重要。
我做错了什么?对此有什么惯用解决方案?
答案 0 :(得分:1)
flatMap
非常友好地取消订阅Observable
,当它启动新的"流"时。制作人可以使用observer.isUnsubscribed
的订阅状态来停止其工作:
function searchInto(observer, query, start) {
runQuery(query, start).subscribe(result => {
observer.next(result);
if (hasMorePages(result) && !observer.isUnsubscribed) {
searchInto(observer, query, start + 1);
} else {
observer.complete();
}
});
}
答案 1 :(得分:1)
int motorPin = 3;
int motorDir = 12;
int motorBr = 9;
void setup() //this is executed only once at init
{
//pinMode(motorPin, OUTPUT);
pinMode(motorBr, OUTPUT);
pinMode(motorDir, OUTPUT);
}
void loop() //This will be executed over and over
{
if (Serial.available() > 0) {
// here '1' (the character) is important as 1 is the number
// and '1' equals 0x31 (ASCII)
if(Serial.read() == '1') {
digitalWrite(motorBr, LOW);
digitalWrite(motorDir, HIGH);
digitalWrite(motorPin, HIGH);
delay(500);
digitalWrite(motorBr, HIGH);
} else if(Serial.read() == '0') {
digitalWrite(motorBr, LOW);
digitalWrite(motorDir, LOW);
digitalWrite(motorPin, HIGH);
delay(500);
digitalWrite(motorBr, HIGH);
}
}
}
只有在您返回可取消的switchMap
时才能取消操作。由于您未在Observable
内退回Subscription
,因此无法取消正在进行的操作。
因为在这种情况下使用Observable.create
并没有真正帮助你,我建议您使用expand
运算符来执行递归操作:
Observable.create