RxJS 基础入门

英文资源

中文资源

实用库

在 Nest.js 中使用

在 Controllers / Services 中使用:

import { Controller, Get } from '@nestjs/common';
import { from, Observable } from 'rxjs';

import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): Observable<number> {
    // return this.appService.getHello();
    return from(Promise.resolve(10));
  }
}

在 Mongoose 中使用

Rx.Observable that can sequentially pull data from a mongoose (mongodb) cursor with fine control over concurrency

import { Observable } from 'rxjs';

// This took me way too long to figure out. Hope this helps someone.
// <3 Well Caffeinated
function fromCursor( cursor ){
    return new Observable((obs) => {
        // is the connection closed
        var closed = false

        // get the next document
        function getNext(){
            return cursor.next((err, doc) => {
                if ( err ){
                    return obs.error( err )
                }
                
                if ( !doc ){
                    // no document so we're done
                    return obs.complete()
                }

                // call next, however we'll pass it an observable
                // that way we delay fetching the next document until
                // the current one is observed
                obs.next(Rx.Observable.defer( () => {
                    if ( !closed ){ getNext() }
                    return Rx.Observable.of(doc)
                }))
            })
        }

        // start
        getNext()

        // cleanup
        return () => {
            closed = true;
            cursor.close();
        }
    })
}

usage example:

const Model = require('some/mongoose/model')
const taskFn = require('some/task/fn') 

function performMaintenance( concurrency = 1 ){
  let query = Model.find({ needsMaintenance: true })

  // this will return an observable stream of the result of taskFn
  return fromCursor( query.cursor() ).mergeMap( obs => {
    // we use mergeMap because we want to perform async tasks on each document
    // we need to use flatMap because we're receiving an observable, not the document!
    
    // taskFn could return an observable, or a promise
    return obs.flatMap( doc => taskFn(doc) )
  }, concurrency)
}

// do stuff
performMaintenance( 2 ).subscribe({
  next: ( result ) => console.log('updated document', result)
  , error: ( err ) => console.error( err )
  , complete: () => console.log('done')
})

示例

方便灵活地数据过滤

import { from, iif, Observable, of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

type Cat = {
  name: string;
  age: number;
};

function filter({ age = '', name = '' }: { age?: string; name?: string } = {}): Observable<Cat[]> {
  return (
    from(
      Promise.resolve([
        //
        { age: 1, name: 's3' },
        { age: 2, name: 's2' },
        { age: 1, name: 's1' }
      ])
    )
      //
      .pipe(
        // 可自由增删过滤的类型
        // Filter by Age
        mergeMap((cats) =>
          iif(
            //
            () => age !== '',
            of(cats.filter((cat) => `${cat.age}` === age)),
            of(cats)
          )
        ),
        // Filter by Name
        mergeMap((cats) =>
          iif(
            //
            () => name !== '',
            of(cats.filter((cat) => cat.name === name)),
            of(cats)
          )
        )
      )
  );
}

filter({
  age: '1',
  name: 's1'
}).subscribe(console.log);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Willin 老王带你躺平养老

感谢你这么好看还这么慷慨

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值