Определить конкретные наблюдаемые конкат в подписке - PullRequest
1 голос
/ 03 октября 2019

Я пытаюсь загрузить несколько файлов последовательно / с чередованием. Когда файл был загружен, я хотел бы показать значок успеха рядом с ним на основе идентификатора файла. Поскольку файлы большого размера, это позволило бы просто управлять загрузкой и повторять определенные файлы в случае ошибки.

Я делаю что-то похожее на это:

var finalObservable: Observable<any> = null;

for (var i = 0; i < this.files.length; i++) {
    var currentFileId = this.files[i].fileId;
    var currentObservable = this.service.getResourceObservable(this.files[i].downloadLink)
                            .map(data => {return {fileId: currentFileId, result:data}});
    if (finalObservable == null) {
        finalObservable = currentObservable;
    } else {
        finalObservable = finalObservable.merge(currentObservable);
    }
}

finalObservable.subscribe(resp => {
    this.downloadService.download(resp.result);
    for (var i = 0; i < this.files.length; i++) {
        if (this.files[i].fileId == resp.fileId)  {
            this.files[i].downloaded = true ;
        }
    }
});

Что происходит, когдаОтправленный fileId всегда this.files[this.files.length-1].fileId. В общем, только последний файл получает downloaded = true.

Я не понимаю, почему ... ты можешь помочь?

Примечание: я опирался на этот вопрос / ответ здесь RxJS Observable.concat: Как узнать, откуда пришел следующий результат?

1 Ответ

2 голосов
/ 04 октября 2019

TL; DR

Попробуйте определить currentFileId с ключевым словом let вместо var:

let currentFileId = this.files[i].fileId;

Объяснение

currentFileId определен в цикле с var ключевое слово (которое определяет переменную во всей области действия функции, независимо от области видимости блока)

for (var i = 0; i < this.files.length; i++) {
    var currentFileId = this.files[i].fileId;
    var currentObservable = this.service.getResourceObservable(this.files[i].downloadLink)
                            .map(data => {return {fileId: currentFileId, result:data}});

Во второй строке тела цикла создаются замыкания, и каждое замыкание получает ссылку на одну и ту же переменную currentFileId . И после цикла fileId последнего файла сохраняется в currentFileId, и каждое замыкание использует одно и то же значение при вызове функции.

Подробное объяснение можно найти в этом ответе https://stackoverflow.com/a/750506/921141

...