Typescript Observables http.post и http.get Вопрос о передаче - PullRequest
0 голосов
/ 23 октября 2018

Я работаю над проектом, в котором я создаю простой внешний интерфейс на Angular (машинопись) / Node для вызова внутреннего сервера для выполнения различных задач.Эти задачи требуют времени для выполнения и, следовательно, должны быть поставлены в очередь на внутреннем сервере.Я решил эту проблему, следуя следующему руководству: https://github.com/realpython/flask-by-example, и все, кажется, работает просто отлично.

Теперь я заканчиваю работу над внешним интерфейсом, где большая часть кода уже написана на Typescript с использованием Angular и Rxjs.Я пытаюсь повторить следующий код в Typescript:

https://github.com/dimoreira/word-frequency/blob/master/static/main.js

Этот код состоит из двух функций, где первая функция "getModelSummary" (в данном примере getResults) вызывает метод post через:

public getModelSummary(modelSummaryParameters: ModelSummaryParameters): Observable<ModelSummary> {

        return this.http.post(`${SERVER_URL}start`, modelSummaryParameters)
            .map(res => res.json())
            ;
    }

, чтобы поставить задание в очередь и назначить для этой функции идентификатор задания на внутреннем сервере.Вторая функция «listenModelSummary», в идеале, должна выполняться сразу после первой функции с заданием jobId в качестве входного сигнала и за короткое время зацикливается, проверяя, выполнено ли задание или нет:

public listenModelSummary(jobID: string) {

    return this.http.get(`${SERVER_URL}results/` + jobID).map(
        (res) => res.json()
    );
}

После выполнения заданиясделано, нужно вернуть результаты, что обновит интерфейс.

Я новичок в Typescript, Observables и rxjs и хотел спросить, как это сделать правильно.Я не хочу использовать javascript, но хочу как можно больше придерживаться Typescript в моем стеке кода переднего плана.Как я могу использовать первую функцию, чтобы вызвать вторую функцию с ее выводом "jobID" и запустить вторую функцию через интервал до тех пор, пока выход не вернется?

Ответы [ 3 ]

0 голосов
/ 23 октября 2018

Вы можете попробовать следующее:

getModelSummary(modelSummaryParameters: ModelSummaryParameters): Promise<ModelSummary> {
  return this.http.post(`${SERVER_URL}start`, modelSummaryParameters).toPromise();
}

async someMethodInYourComponent() {
  const modelSummary = await this.get(modelSummary(params);
  this.listenModelSummary(modelSummary)
}

// OR
someMethodInYourComponent() {
  this.get(modelSummary(params).then(() => {
    this.listenModelSummary(modelSummary);
  });
}
0 голосов
/ 25 октября 2018

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

В своих службах я создал две наблюдаемые:

  1. Сначала нужно получить идентификатор задания, возвращенный сервером очередей: // API: GET / FUNCTION /:jobID public getModelSummaryQueueId(modelSummaryParameters: ModelSummaryParameters): Observable<JobId>{ return this.http.post( $ {SERVER_URL} start , modelSummaryParameters).map( (jobId) => jobId.json() ) }
  2. Используйте jobId из первого сегмента для извлечения данных: // API: GET / FUNCTION /:results public listenModelSummary(jobId: JobId): Observable <ModelSummary>{ return this.http.get( $ {SERVER_URL} results / + jobId).map( (res) => res.json() ) }
  3. Ниже представлен компонент, который работает с двумя вышеуказанными службами:

`

this.subscription = this.developmentService.getModelSummaryQueueId(this.modelSummaryParameters)
    .subscribe((jobId) => {
return this.developmentService.listenModelSummary(jobId)
    // use switchMap to pull value from observable and check if it completes
    .switchMap((modelSummary) =>
        // if value has not changed then invoke observable again else return
        modelSummary.toString() === 'Nay!'
            ? Observable.throw(console.log('...Processing Request...'))
            // ? Observable.throw(this.modelSummary = modelSummary)
            : Observable.of(modelSummary)
    )
.retryWhen((attempts) => {
    return Observable
    // specify number of attempts
        .range(1,20)
        .zip(attempts, function(i) {
            return(i);
        })
        .flatMap((res:any) => {
            // res is a counter of how many attempts
            console.log("number of attempts: ", res);
            res = 'heartbeat - ' + res
            this.getProgressBar(res);
            // this.res = res;
            // delay request
            return Observable.of(res).delay(100)
        })
})
// .subscribe(this.displayData);
// .subscribe(modelSummary => console.log(modelSummary));
.subscribe((modelSummary) => {
    console.log("FINAL RESULT: ", modelSummary)
    this.modelSummary = modelSummary;
    this.getProgressBar('Done');
});

});

`

0 голосов
/ 23 октября 2018

Observables великолепны и являются типом объектов, возвращаемых классом Angular HttpClient, но иногда, на мой взгляд, иметь дело с ними намного сложнее, чем с использованием обещаний.

Да, есть небольшоеснижение производительности для дополнительной операции по преобразованию Observable в Promise, но вы получаете более простую модель программирования.

Если вам нужно дождаться завершения первой функции, а затем передать возвращенное значение другой функции,Вы можете сделать:

async getModelSummary(modelSummaryParameters: ModelSummaryParameters): Promise<ModelSummary> {
  return this.http.post(`${SERVER_URL}start`, modelSummaryParameters).toPromise();
}

async doStuff(): Promise<void> {
  const modelSummary = await this.getModelSummary(params);

  // not sure if you need to assign this to your viewmodel,
  // what's returned, etc
  this.listenModelSummary(modelSummary)
}

Если вы не можете использовать Observables, я бы предложил использовать шаблон concatMap, который будет выглядеть примерно так:

doStuff(modelSummaryParameters: ModelSummaryParameters): Observable<ModelSummary> {
  return this.http
             .post(`${SERVER_URL}start`, modelSummaryParameters)
             .pipe(
               concatMap(modelSummary => <Observable<ModelSummary>> this.listenModelSummary(modelSummary))
             );
}

Вотстатья о различных картографических решениях для Observables: https://blog.angularindepth.com/practical-rxjs-in-the-wild-requests-with-concatmap-vs-mergemap-vs-forkjoin-11e5b2efe293, которые могут вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...