Angular 7 个来自可观察订阅的奇怪行为

Angular 7 Weird behavior from observable subscription

我有一个代码来处理一些来自可观察对象的数据,这个可观察对象是通过@Input 注释获取的,我在我的 NgOnInit() 中订阅了可观察对象,一切正常,但我需要添加减少数据处理时间的代码,这是一个数组数组,我的数据是这样的:

[['id1',对象,对象],['id2',对象,对象]]

所以为了减少处理时间,我创建了一个变量来保存 Observable 之前 post 处理过的值,我将之前的数据与新数据进行比较,并只更新发生变化的数据,我的代码如下所示:

 private dataSetHolder: Array<any> = [];

constructor() { }


ngOnInit() {
    this.dataSet$.subscribe(data => { //line 43
        console.log('inicio: ', this.dataSetHolder);
        data.forEach(array => {
            const dataNoId = Object.assign([], array);
            const id = array[0];
            dataNoId.shift();
            let pacote: Package = { eixo_x: [], eixo_y: [] };
            if (this.dataSetHolder.length === 0) {
                pacote = this.separaDados(dataNoId, id, pacote);
                this.loadData(pacote);
            } else {
                this.dataSetHolder.forEach(arrayHolder => {
                    if (id === arrayHolder[0]) {
                        if (array.length > arrayHolder.length) {
                            pacote = this.separaDados(dataNoId, id, pacote);
                            this.loadData(pacote);
                        }
                    }
                });
            }
        });
        this.dataSetHolder = data; //line 64
    });
}

当第64行执行时,数据的当前值被传递给this.dataSetHolder,当observable收到一个新值时,再次执行第43行,当第43行执行时[=43的值=] 已更新,这不应该发生,它应该只在第 64 行更新。

有人知道那里发生了什么吗?

请注意,从最后一张图片到下一张我没有点击继续调试,我还在第 44 行

我也试过将第 64 行改成这个

            this.dataSetHolder = Object.assign([], data);

因为我认为这可能是由javascript引起的,因为当我这样做时this.dataSetHolder = data;它实际上并没有传递对象,只是传递了引用,但它仍然不起作用。

我的最终代码如下所示:

    ngOnInit() {
    this.dataSet$.subscribe(data => {
        data.forEach(array => {
            const dataNoId = Object.assign([], array);
            const id = array[0];
            dataNoId.shift();
            let pacote: Package = { eixo_x: [], eixo_y: [] };
            if (this.dataSetHolder.length === 0) {
                pacote = this.separaDados(dataNoId, id, pacote);
                this.loadData(pacote);
            } else {
                this.dataSetHolder.forEach(arrayHolder => {
                    if (id === arrayHolder[0]) {
                        const length = Object.keys(arrayHolder).length;
                        if (array.length > length) {
                            pacote = this.separaDados(dataNoId, id, pacote);
                            this.loadData(pacote);
                        }
                    }
                });
            }
        });
        this.dataSetHolder = [];
        data.forEach(dataItem => this.dataSetHolder.push({... dataItem}));
    });
}

多亏了 bmtheo 的评论,我解决了问题,正如他所解释的,即使使用 Object.assign() 复制数据是不够的,因为我的数据是数组的数组,当我使用Object.assign() 我复制了我的数组的第一级,但第二级数组没有被复制,它们被引用,这就是每次有新值可用时数据都会改变的原因。

解决方法是清空我的数组,然后将每个子数组复制到它里面。除此之外,我还改变了获取 arrayHolder 长度的方式,因为它不再被解释为数组,而是被视为对象, 不影响其余部分代码,所以我将此 const length = Object.keys(arrayHolder).length; 添加到我的代码中。