Rx.js无法获得值

Rx.js无法获得值

问题描述:

我想要获得最后3个值,发布代码后,我期待在填充uiOrder和调用cancelOrderItem()几次之后,我可以访问最后3个修订版本的命令与getHistory(),但我实际上获得最后(当前)值3倍,我已经尝试replaySubject(3)具有相同的结果。 这是我的代码:Rx.js无法获得值

export class OrdersService { 

    public readonly orders: Observable<Order[]>; 
    public readonly uiOrder: Observable<Order>; 

    private _orders: BehaviorSubject<Order[]>; 
    private _uiOrder: BehaviorSubject<Order>; 

    private dataStore: { 
    uiOrder: Order, 
    orders: Order[] 
}; 


    constructor() { 

    this.dataStore = { 
     uiOrder: null, 
     orders: [] 
    }; 

    this._orders = <BehaviorSubject<Order[]>>new BehaviorSubject([]); 
    this._uiOrder = <BehaviorSubject<Order>>new BehaviorSubject({}); 
    this.orders = this._orders.asObservable(); 
    this.uiOrder = this._uiOrder.asObservable(); 
    } 

    getOrder(orderId: number | string) { 
    for (let i = 0; i < this.dataStore.orders.length; i++) { 
     if (this.dataStore.orders[i].id == orderId) { 
     this.dataStore.orders[i].lastAccess = moment().format().slice(0, 19) + 'Z'; 
     this.dataStore.uiOrder = this.dataStore.orders[i]; 
     this.updateUiOrder(); 
     } 
    } 
    } 


    cancelOrderItem(action) { 
    this.dataStore.uiOrder.sections[action.sectionIndex].orderDetails.splice(action.orderDetailsIndex, 1); 
    this.updateUiOrder() 
    } 

    getHistory() { 
    this.uiOrder.take(3).subscribe((res) => { 
     console.log('uiOrder', res); 
    }).unsubscribe() 
    } 

    updateUiOrder() { 
    console.log('updating ui order'); 
    this._uiOrder.next(this.dataStore.uiOrder); 
    } 

} 

我做错了什么?

您正在查找的操作员是bufferCount(3,1),它会创建最后3个值的滑动窗口。下行:只有在积累了3个数值后才会开始发射。如果你想拥有的第一个值,你可以做这样的事情:

Rx.Observable.from([null,null]) 
    .concat(this.uiOrder) 
    .bufferCount(3,1) 
    .subscribe(uiOrderHistory => ...); 

这样,你的大理石图将如下所示:

---Order1-----------------Order2--------------------Order3 
bufferCount(3,1) 
---[null,null,Order1]-----[null,Order1,Order2]------[Order1,Order2,Order3] 

getHistory() { 
this.uiOrder.takeLast(3).subscribe((res) => { 
    console.log('uiOrder', res); 
}).unsubscribe() } 

  takeLast操作者检索来自源可观察到的发射的最后三个值。

+1

谢谢,但takeLast(N)将发出最后n值只有在源代码完成后,这不是我正在寻找的行为。 –

您可能正在反思。如果您需要随时可用的最近3个订单,为什么不将它们存储在每次uiOrder发出新订单时都会更新的数组中?

orderHistory:Order[] = []; 

orders$ = this.uiOrder.subscribe(order => 
    let h = this.orderHistory; 
    //add the order to history array: 
    h = [...h, order]; 
    //splice the array to keep only the last 3 orders: 
    if (h.length > 3) h.splice(0,h.length-3) 
); 

现在,每当你想知道最近的3个数量级,就看orderHistory。作为奖励,该查找是同步操作。

+1

我想到了这种方法,但是不是观察者随时间推移提供价值的重点吗? –

+0

@MoshikHasky我首先使用Observables写了一个答案,但改变了我的想法bc它不必要的复杂 - 它使用了一个辅助流来观察第一个流,并使用['scan'](https://www.learnrxjs .io/operators/transformation/scan.html)操作员在每次源发出新订单时跟踪并发送数组中的最后3个订单。因为这是一个更简单,更易于阅读和调试的方法,所以我认为它更好。更不用说更少的资源,因为没有必要设置新的对象,新的流,新的观察者...... – BeetleJuice

+0

我会标记你的答案,但只是为了我的替代标记Observables更好,你能分享一段代码扫描会看起来像? –