You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5中如何直接赋值Observable变量?无需mergeMap与scan

Alternative Ways to Update Your $groups Observable Without mergeMap and scan

Hey there! Let's start by breaking down what your original code does: it takes your this.groups array, prepends an empty array, then emits each element with a 1-second delay between them. Finally, scan accumulates these elements into a growing array, so your $groups observable emits a new array every second with all previous items plus the latest one.

If you want to avoid mergeMap and scan and instead have a more "direct assignment" feel, BehaviorSubject is absolutely the right tool here—you just might not have used it the right way to replicate the accumulation behavior. Here's a step-by-step solution:


Solution 1: Use BehaviorSubject with Manual Interval Updates

A BehaviorSubject holds the current value and emits it to new subscribers, which makes it perfect for maintaining your growing array state. You can manually push updates to it on a timer:

// Initialize with an empty array as the initial value
private $groups = new BehaviorSubject<any[]>([]);

// Function to push groups one by one with 1-second delays
private startEmittingGroups(): void {
  let currentIndex = 0;
  const emitNext = () => {
    if (currentIndex >= this.groups.length) return;

    // Get the current array state, add the next group, and push the new array
    const currentArray = this.$groups.value;
    const updatedArray = [...currentArray, this.groups[currentIndex]];
    this.$groups.next(updatedArray);

    currentIndex++;
    setTimeout(emitNext, 1000);
  };

  emitNext();
}

// Call this when you want to start emitting (e.g., in ngOnInit if using Angular)
ngOnInit(): void {
  this.startEmittingGroups();
}

This approach matches your original behavior exactly:

  • $groups emits a new array every second
  • Each new array includes all previous groups plus the latest one
  • No mergeMap or scan needed—you're directly controlling the state and emissions

Why Your Previous Subject Attempt Might Have Failed

If you tried a regular Subject instead of BehaviorSubject, it doesn't hold a current value—so you couldn't easily access the existing array to append new items. A BehaviorSubject solves this by letting you get the latest emitted value with .value, which is key for building the updated array.


Bonus: Simplified Version (No mergeMap, but still uses scan)

If you're open to keeping scan but ditching mergeMap, you can use delayWhen to handle the timing instead:

this.$groups = from(this.groups)
  .pipe(
    delayWhen((_, index) => timer(index * 1000)),
    scan((acc, curr) => [...acc, curr], [])
  );

This is more concise, but since you asked to avoid scan, the BehaviorSubject approach is your best bet for that "direct assignment" control you're looking for.

内容的提问来源于stack exchange,提问作者Sudhanshu sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:22:40