2016-12-25 3 views
3

Я пишу настольное приложение с использованием углового2 и электрона, и есть функция загрузки.Angular2 - Rxjs Subject запускается дважды даже после отмены подписки

Мои DownloadService это

import {Injectable} from '@angular/core'; 
import {Subject} from "rxjs"; 

interface IQueueItem { 
    url: string 
} 

@Injectable() 
export class DownloadService { 
    private queue: Array<IQueueItem> = []; 

    private downloadSubject: Subject<any>; 

    constructor() { 
     this.downloadSubject = new Subject(); 
    } 

    addToList(item: IQueueItem) { 
     this.queue.unshift(item); 

     downloadList(); 

     return this.downloadSubject; 
    } 

    downloadList() { 
     // pick one item from queue and send it to electron to download and store 

     // do this every time a chunk of data received 
     this.downloadSubject.next(evt); 
     ... 
    } 

    pauseDownload(item) { 
     // send an event to electron to it should stop downloading and therefore no chunk of data will receive 
     // also remove item from queue 
     ... 
    } 
} 

И мой ItemComponent это:

import {Component} from '@angular/core'; 
import {DownloadService} from "../services/download.service"; 

@Component({ 
    selector: 'app-item', 
    template: ` 
     ... 
     ` 
}) 
export class ItemComponent { 
    constructor(private downloadService: DownloadService) { 
     this.addToQueue(); 
    } 

    subscription; 

    downloadedBytes = 0; 

    fileUrl = ''; 

    pause() { 
     this.downloadService.pauseDownload(this.fileUrl); 

     this.subscription.unsubscribe(); 

     ... 
    } 

    resume() { 
     this.addToQueue(); 
    } 

    private addToQueue() { 
     this.subscription = this.downloadService.addToList(this.fileUrl) 
      .subscribe(evt => { 

       console.log(evt.delta); 

       this.downloadedBytes += evt.delta; 
      }); 
    } 
} 

Проблема заключается в том, когда я Приостановка деталь я отказаться от подписки Subject передается от DownloadService, но когда я возвращаюсь снова, каждый console.log() печатает дважды и добавляет дважды данные в downloadedBytes. Также, если я снова приостанавливаю и возобновляю, он будет добавлять все больше и больше байтов и журналов!

Я искал, но не нашел подсказки для решения.

+1

Я предполагаю, что это происходит от того, что downloadList() добавляет компонент в список. Но поскольку мы не знаем, для чего этот список, когда субъект испускает события, для чего он используется, что делает pauseCourse() и т. Д., Его трудно объяснить. Предоставьте полный пример, воспроизводящий проблему. –

+0

@JBNizet жаль, что я сделал много упрощения, и, видимо, результат был неудачным. Я добавил дополнительные сведения –

+1

Я не могу воспроизвести его https://plnkr.co/edit/64mn6U1omy8JPE6LD4Nf?p=preview. Проверьте также http://stackoverflow.com/questions/35673582/http-request-made-multiple-times-in-angular2-service – yurzui

ответ

2

Вы можете видеть из PLUNKER созданного yurzui, что если вы резюме и паузы все работает, как и ожидалось, срабатывает только один раз .
Вопрос в том, когда вы нажимаете резюме, 2 раза подряд как первой подписки будут потеряны в памяти, и только второй один будет храниться в this.subscription доступ к первому является потеряны, и вы не можете отказаться от подписки.
Это больше похоже на проблему с приложением, чем на rxjs. Если подписка не приостановлена, вы не сможете щелкнуть ее, так что вам нужно правильно обрабатывать состояния, что-то вроде этого (отредактировано с помощью @yurzui plunker):

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h1>Angular 2 Systemjs start</h1> 
    <button *ngIf="started && !paused" (click)="pause()">Pause</button> 
    <button *ngIf="started && paused" (click)="resume()">Resume</button> 
    <button *ngIf="!started" (click)="start()">Start</button> 
    ` 
}) 
export class App { 
    constructor(private downloadService: DownloadService) { 
    this.addToQueue(); 
    } 

    subscription; 
    downloadedBytes = 0; 
    started = false; 
    paused = false; 


    pause() { 
    this.paused = true; 

    this.subscription.unsubscribe(); 
    } 

    start() { 
    this.started = true; 

    this.addToQueue(); 
    } 

    resume() { 
    this.paused = false; 

    this.addToQueue(); 
    } 

    private addToQueue() { 
    this.subscription = this.downloadService.addToList(this) 
     .subscribe(evt => { 

     console.log(11); 

     this.downloadedBytes += evt.delta; 
     }); 
    } 
} 

Вы можете найти рабочий пример в этой обновленной PLUNKER

 Смежные вопросы

  • Нет связанных вопросов^_^