RxJS mix combineLatest和zip

时间:2018-02-01 07:24:21

标签: javascript rxjs

我有两个流源,我想听听它们。要求是:

  1. 如果一个人发出也给我第二个的最后一个值。
  2. 如果其中两个同时发出,请不要两次拨打订阅。
  3. 第一种情况是combineLatest,但第二种情况是zip。我需要一种方法将combineLatest和zip混合到一个运算符中。

    const { Observable, BehaviorSubject} = Rx;
    
    const movies = {
      ids: [],
      entities: {}
    }
    
    const actors = {
      ids: [],
      entities: {}
    } 
    
    const storeOne = new BehaviorSubject(movies);
    const storeTwo = new BehaviorSubject(actors);
    
    const movies$ = storeOne.map(state => state.entities).distinctUntilChanged();
    const actors$ = storeTwo.map(state => state.entities).distinctUntilChanged();
    
    const both$ = Observable.zip(
       movies$,
       actors$,
       (movies, actors) => {
         return {movies, actors};
       }
    )
    
    both$.subscribe(console.log);
    
    storeOne.next({
      ...storeOne.getValue(),
      entities: {
        1: {id: 1}
      },
      ids: [1]
    });
    
    storeTwo.next({
      ...storeTwo.getValue(),
      entities: {
        1: {id: 1}
      },
      ids: [1]
    });
    

    上面的代码在两者一个接一个地发出时工作正常,但我还需要支持其中一个发出的情况。 (combineLatest)

    我该怎么做?

1 个答案:

答案 0 :(得分:2)

是的,根据@cartant的建议,您可以使用/* Default environment */ #ifndef CONFIG_EXTRA_ENV_SETTINGS #define CONFIG_EXTRA_ENV_SETTINGS \ "fit_image=fit.itb\0" \ "load_addr=0x2000000\0" \ "fit_size=0x800000\0" \ "flash_off=0x100000\0" \ "nor_flash_off=0xE2100000\0" \ "fdt_high=0x20000000\0" \ "initrd_high=0x20000000\0" \ "loadbootenv_addr=0x2000000\0" \ "bootenv=uEnv.txt\0" \ "bootenv_dev=mmc\0" \ "loadbootenv=load ${bootenv_dev} 0 ${loadbootenv_addr} ${bootenv}\0" \ "importbootenv=echo Importing environment from ${bootenv_dev} ...; " \ "env import -t ${loadbootenv_addr} $filesize\0" \ "bootenv_existence_test=test -e ${bootenv_dev} 0 /${bootenv}\0" \ "setbootenv=if env run bootenv_existence_test; then " \ "if env run loadbootenv; then " \ "env run importbootenv; " \ "fi; " \ "fi; \0" \ "sd_loadbootenv=set bootenv_dev mmc && " \ "run setbootenv \0" \ "usb_loadbootenv=set bootenv_dev usb && usb start && run setbootenv \0" \ "preboot=if test $modeboot = sdboot; then " \ "run sd_loadbootenv; " \ "echo Checking if uenvcmd is set ...; " \ "if test -n $uenvcmd; then " \ "echo Running uenvcmd ...; " \ "run uenvcmd; " \ "fi; " \ "fi; \0" \ "norboot=echo Copying FIT from NOR flash to RAM... && " \ "cp.b ${nor_flash_off} ${load_addr} ${fit_size} && " \ "bootm ${load_addr}\0" \ "kernel_image=uImage\0" \ "kernel_load_address=0x2080000\0" \ "ramdisk_image=uramdisk.image.gz\0" \ "ramdisk_load_address=0x4000000\0" \ "devicetree_image=devicetree.dtb\0" \ "devicetree_load_address=0x2000000\0" \ "sdboot=if mmcinfo; then " \ "echo Copying Linux from SD to RAM... && " \ "load mmc 0 ${kernel_load_address} ${kernel_image} && " \ "load mmc 0 ${devicetree_load_address} ${devicetree_image} && " \ "bootm ${kernel_load_address} - ${devicetree_load_address}; " \ "fi\0" \ "jtagboot=echo TFTPing FIT to RAM... && " \ "tftpboot ${load_addr} ${fit_image} && " \ "bootm ${load_addr}\0" \ "usbboot=if usb start; then " \ "echo Copying FIT from USB to RAM... && " \ "load usb 0 ${load_addr} ${fit_image} && " \ "bootm ${load_addr}; fi\0" \ DFU_ALT_INFO #endif

详细说明,

  1. Observable.combineLatest(movies$, actors$, (movies, actors) => ({ movies, actors })).auditTime(0)将等待auditTime(n)毫秒并发出最新值。
  2. n类似于auditTime(0),它实际上不等待(立即执行),但等待当前事件/执行循环完成。
  3. Example

    此处值为setTimeout(0)& B一起发出,因此当您使用combineLatest时,您将获得2B1B2(基于内部时钟)。无论A2, B2是该执行循环中的最新值。由于我们正在等待B2,即当前执行循环通过0 milliseconds获取最新值,因此observable将仅发出auditTime(0)