установить задержку динамического на повтор - PullRequest
0 голосов
/ 03 января 2019

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

imageController(epgData: EpgDataDTO[], showOrMovie: string){
    var retryAfterMilliSeconds = 1000;
    epgData.forEach( (data) => {
        this.getImagesFromMovieDB(data.title).pipe(
            retryWhen((error) => {
                return error.pipe(
                    mergeMap((error: any) => {
                            if(error.response.status === 429) {
                                const retryAfter = error.response.headers;
                                retryAfterMilliSeconds = +retryAfter['retry-after'] * 1000
                                console.log(retryAfterMilliSeconds); // it tells me the correct value here but the retry happens every 1000ms
                                console.log(data.title);
                            }else{
                                this.errorHandling(error)
                                return of("error");
                            }
                            return of("error");
                        }),
                    delay(retryAfterMilliSeconds),
                    take(5)
                )
        }))
        .subscribe( (res) => {
            console.log(res.status);
            console.log(res.headers);

        });
    })
}

1 Ответ

0 голосов
/ 04 января 2019

Вы были ОЧЕНЬ близки!Чтобы заставить это работать, все, что мне нужно было сделать, это переместить delay(retryAfterMilliSeconds) после возвращаемого значения оператора mergeMap(), чтобы привязать его к той же самой наблюдаемой.Без этого он случайным образом задержал бы ВОЗВРАТ с mergeMap(), который был бы случайным, для которого фактически наблюдалась задержка.

Я положил это в Stackblitz , чтобы проверить его.Нажмите «Консоль» в нижней части крайне правого кадра, чтобы увидеть результаты.

Вот функция из этого StackBlitz:

imageController(epgData: EpgDataDTO[], showOrMovie: string){
    var retryAfterMilliSeconds = 1000;
    epgData.forEach( (data) => {
        this.getImagesFromMovieDB(data.title).pipe(
            retryWhen((error) => {
                return error.pipe(
                    mergeMap((error: any) => {
                            if(error.response.status === 429) {
                                const retryAfter = error.response.headers;
                                retryAfterMilliSeconds = +retryAfter['retry-after'] * 1000
                                console.log(retryAfterMilliSeconds); // it tells me the correct value here but the retry happens every 1000ms
                                console.log(data.title);
                            }else{
                                this.errorHandling(error)
                                // return of("error"); <-- unnecessary since this will be executed with next statement
                            }
                            return of("error").pipe(delay(retryAfterMilliSeconds));
                        }),
                    // delay(retryAfterMilliSeconds),
                    take(5)
                )
        }))
        .subscribe( 
            (res) => {
                // console.log(res.status);
                // console.log(res.headers);
                const elapsedTime = Math.round(((new Date()).getTime() - startTime) / 1000);
                console.log(`'${res.status}' is Ok - total elapsed time ${elapsedTime} seconds`);
            }
        );
    })
}

Некоторые другие примечания:

  • Возвращение с getImagesFromMovieDB() на самом деле важно - для каждого вызова необходимо возвращать уникальную наблюдаемую величину для каждого вызова, пожалуйста, убедитесь, что это так.Я смоделировал это в StackBlitz, построив возвращаемое значение Observable с помощью delay.
  • . Как вы можете видеть, я изменил первую функцию внутри .subscribe(), чтобы распечатать общее истекшее время, необходимое для получения действительных данных для этогоres.status.Я сделал это только для того, чтобы показать для каждого излучения, что оно правильно принимает сумму всех задержек.Он повторяется после каждого сбоя в течение произвольного промежутка времени (я произвольно выбрал от 5 до 10 секунд), как и возвращается заголовком ответа в вашей исходной функции.
  • Незначительный момент: у вас есть два возврата из mergeMap return of("error") но первое не нужно, так как второе будет выполнено немедленно, поэтому я прокомментировал это.

Надеюсь, это поможет.

...