郑英弥 發表於 2023-4-10 16:02:00

rxjs的几点使用心得

<p><span style="font-size: 18pt">1.对错误的处理</span></p>
<p>日常使用中,点击按钮需要往后台发消息,为了不重复发消息,经常需要把点击事件做成subject,然后把发消息的过程做成switchMap,类似下面的写法</p>
<div class="cnblogs_code">
<div>
<div>
<div>&nbsp; &nbsp; const subject = new rxjs.Subject();</div>
<br>
<div>&nbsp; &nbsp; subject.pipe(</div>
<div>&nbsp; &nbsp; &nbsp; rxjs.operators.switchMap(index =&gt; {</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; return rxjs.of(index);</div>
<div>&nbsp; &nbsp; &nbsp; })</div>
<div>&nbsp; &nbsp; ).subscribe({</div>
<div>&nbsp; &nbsp; &nbsp; next: console.log,</div>
<div>&nbsp; &nbsp; &nbsp; error: err =&gt; console.error('error2', err),</div>
<div>&nbsp; &nbsp; &nbsp; complete: () =&gt; console.log('complete')</div>
<div>&nbsp; &nbsp; });</div>

<br>
<div>&nbsp; &nbsp; subject.next(1);</div>
<div>&nbsp; &nbsp; subject.next(2);</div>
<div>&nbsp; &nbsp; subject.next(3);</div>
<div>&nbsp; &nbsp; subject.next(4);</div>
<div>&nbsp; &nbsp; 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>=&gt;<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>=&gt; console.error('error2'<span style="color: rgba(0, 0, 0, 1)">, err),
      complete: () </span>=&gt; 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>=&gt;<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>=&gt;<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>=&gt; console.error('error2'<span style="color: rgba(0, 0, 0, 1)">, err),
      complete: () </span>=&gt; 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>=&gt;<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>=&gt;<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>=&gt; 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) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      setTimeout(() </span>=&gt; 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(() =&gt; observer.error(new Error('error')), 3000);</span>
      setTimeout(() =&gt; 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) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      setTimeout(() </span>=&gt; 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(() =&gt; observer.next('b2'), 3000);</span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> setTimeout(() =&gt; observer.next('b3'), 3300);</span>
      setTimeout(() =&gt; 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>=&gt; console.error('error123'<span style="color: rgba(0, 0, 0, 1)">, err),
      complete: () </span>=&gt; console.log('complete'<span style="color: rgba(0, 0, 0, 1)">)
    });</span></pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/chen8840/p/17303241.html
頁: [1]
查看完整版本: rxjs的几点使用心得