与嵌套可观察变量共享运算符

时间:2020-10-13 13:27:23

标签: angular rxjs ngxs

我创建一个游戏模块,负责加载玩家的buildings,然后将获取的对象修改为包含附加字段- remainingTime 的扩展建筑类,并通知多少秒剩下来完成建筑物的升级(此字段每秒刷新一次)。

buildings-> buildingsWithDiff-> buildingsWithTimer

  1. 正在加载buildings
  2. buildings映射到buildingsWithDiff,以了解计时器开始日期结束升级日期之间的差异
  3. buildingsWithDiff映射到buildingsWithTimer,这会从产生的差异
  4. 中减去滴答声数量
class Building {
  name: string;
  lvl: number;
  endDate: Date; // date of upgrading of the building
}

class BuildingWithDiff extends Building {
  diffTime: number; // difference of seconds between the currentDate and the endDate;
}

class BuildingWithTimer extends BuildingWithDiff {
  remainingTime: number; // seconds left to complete upgrading a building
}

/* ------------- */

const getBuildings$ = (store: Store): Observable<Building[]> => {
  const buildings$: Observable<Building[]> = store.select(
    (appState: AppState) => appState.buildings
  ); // source
  return buildings$;
};

const getBuildingsWithTimers$ = (
  store: Store
): Observable<BuildingWithTimer[]> => {
  const buildings$: Observable<Building[]> = getBuildings$(store);

  const buildingsWithDiff$: Observable<BuildingWithDiff[]> = buildings$.pipe(
    map((buildings) =>
      buildings.map((building) => {
        const currentDate: Date = new Date();
        const diffTime: number =
          Math.ceil(
            building.endDate.getTime() - currentDate.getTime()
          ) / 1000;

        return {
          ...building,
          diffTime,
        };
      })
    )
  );

  const buildingsWithTimer$: Observable<BuildingWithTimer[]> = buildingsWithDiff$.pipe(
    switchMap((buildingsWithDiff) =>
      timer(0, 1000).pipe(
        map((tick: number) =>
          buildingsWithDiff.map((buildingWithDiff) => {
            const remainingTime: number = buildingWithDiff.diffTime - tick;

            return {
              ...buildingWithDiff,
              remainingTime,
            };
          })
        )
      ),
      // share()? - it doesn't work :(
    )
  );

  return buildingsWithTimer$;
};

多播嵌套计时器-如何?

订阅上面的选择器会产生错误,因为有多个观察者,并且并非所有观察者都同时运行。添加share运算符不起作用。问题可能在哪里?

有两个地方可以订阅:

  • trigger-在ngxsOnInit中调用的函数(等待remainingTime <= 0调度适当的操作)
  • building component-显示剩余时间的角度分量

当我在该组件所在的子页面上打开应用程序时,它运行良好-两个观察者在计时器中都显示相同的刻度值

问题是当我退出组件所在的子页面时,因为trigger一直有效,并且滴答声仍在计数,但是组件结束了订阅,并且在我需要时要返回到子页面,刻度从零开始计数。

最终,有两个不同的滴答声。

0 个答案:

没有答案