rxjs的几点使用心得
<p><span style="font-size: 18pt">1.对错误的处理</span></p><p>日常使用中,点击按钮需要往后台发消息,为了不重复发消息,经常需要把点击事件做成subject,然后把发消息的过程做成switchMap,类似下面的写法</p>
<div class="cnblogs_code">
<div>
<div>
<div> const subject = new rxjs.Subject();</div>
<br>
<div> subject.pipe(</div>
<div> rxjs.operators.switchMap(index => {</div>
<div> return rxjs.of(index);</div>
<div> })</div>
<div> ).subscribe({</div>
<div> next: console.log,</div>
<div> error: err => console.error('error2', err),</div>
<div> complete: () => console.log('complete')</div>
<div> });</div>
<br>
<div> subject.next(1);</div>
<div> subject.next(2);</div>
<div> subject.next(3);</div>
<div> subject.next(4);</div>
<div> subject.complete();</div>
</div>
</div>
</div>
<p>但是如果某一个发消息的observer报了一个500错误,那么会导致后面的点击事件不会继续调用发消息的过程。</p>
<div class="cnblogs_code">
<pre> const subject = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> rxjs.Subject();
subject.pipe(
rxjs.operators.switchMap(index </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (index === 2<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> rxjs.throwError(<span style="color: rgba(0, 0, 255, 1)">new</span> Error('error'<span style="color: rgba(0, 0, 0, 1)">));
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rxjs.of(index);
})
).subscribe({
next: console.log,
error: err </span>=> console.error('error2'<span style="color: rgba(0, 0, 0, 1)">, err),
complete: () </span>=> console.log('complete'<span style="color: rgba(0, 0, 0, 1)">)
});
subject.next(</span>1<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>2<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>3<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>4<span style="color: rgba(0, 0, 0, 1)">);
subject.complete();</span></pre>
</div>
<p>如上,当index等于2时,rxjs抛出错误,后面的3,4都不会执行了。</p>
<p>为了使后台的错误不影响rxjs,我们需要对switchMap里面的observer做catchError的特殊处理。如下:</p>
<div class="cnblogs_code">
<pre> const subject = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> rxjs.Subject();
subject.pipe(
rxjs.operators.switchMap(index </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (index === 2<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> rxjs.throwError(<span style="color: rgba(0, 0, 255, 1)">new</span> Error('error'<span style="color: rgba(0, 0, 0, 1)">)).pipe(
rxjs.operators.catchError(err </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rxjs.empty();
})
);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rxjs.of(index);
})
).subscribe({
next: console.log,
error: err </span>=> console.error('error2'<span style="color: rgba(0, 0, 0, 1)">, err),
complete: () </span>=> console.log('complete'<span style="color: rgba(0, 0, 0, 1)">)
});
subject.next(</span>1<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>2<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>3<span style="color: rgba(0, 0, 0, 1)">);
subject.next(</span>4<span style="color: rgba(0, 0, 0, 1)">);
subject.complete();</span></pre>
</div>
<p>这样做会跳过抛出错误<span style="font-size: 14px">的后台请求,保证rxjs继续往下执</span>行。</p>
<p><span style="font-size: 18pt">2.如何保证loading = false必执行</span></p>
<p><span style="font-size: 14px">如果rxjs抛出错误,</span>subscribe的error分支会执行,complete分支不会执行</p>
<p>如果rxjs不抛出错误结束,subscribe的error分支不会执行,complete分支会执行</p>
<p>有个操作符,不管抛不抛出错误,他都会执行。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> loading = <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
rxjs.from([</span>1,2,3<span style="color: rgba(0, 0, 0, 1)">]).pipe(
rxjs.operators.map(i </span>=><span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (i === 2<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">throw</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Error('error'<span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> i;
}),
rxjs.operators.finalize(() </span>=><span style="color: rgba(0, 0, 0, 1)"> {
console.log(</span>'set loading'<span style="color: rgba(0, 0, 0, 1)">)
loading </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
})
).subscribe({
next: console.log,
error: console.error,
complete: () </span>=> console.log('complete'<span style="color: rgba(0, 0, 0, 1)">)
});</span></pre>
</div>
<p><span style="font-size: 18pt">3.如何依次发送后台请求</span></p>
<p><span style="font-size: 14px">碰到需要同时发送后台请求时,一般使用forkjoin方法。</span></p>
<p><span style="font-size: 14px">如果请求A依赖于请求B的结果,需要A返回后再发送请求B。这时可以用concat配合</span>bufferCount操作符来实现</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">var</span> a = rxjs.Observable.create((observer) =><span style="color: rgba(0, 0, 0, 1)"> {
setTimeout(() </span>=> observer.next('a1'), 2000<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> setTimeout(() => observer.error(new Error('error')), 3000);</span>
setTimeout(() => observer.complete(), 4000<span style="color: rgba(0, 0, 0, 1)">);
});
</span><span style="color: rgba(0, 0, 255, 1)">var</span> b = rxjs.Observable.create((observer) =><span style="color: rgba(0, 0, 0, 1)"> {
setTimeout(() </span>=> observer.next('b1'), 2000<span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> setTimeout(() => observer.next('b2'), 3000);</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> setTimeout(() => observer.next('b3'), 3300);</span>
setTimeout(() => observer.complete(), 4000<span style="color: rgba(0, 0, 0, 1)">);
});
rxjs.concat(a, b).pipe(
rxjs.operators.bufferCount(</span>2<span style="color: rgba(0, 0, 0, 1)">),
).subscribe({
next: console.log,
error: err </span>=> console.error('error123'<span style="color: rgba(0, 0, 0, 1)">, err),
complete: () </span>=> console.log('complete'<span style="color: rgba(0, 0, 0, 1)">)
});</span></pre>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/chen8840/p/17303241.html
頁:
[1]