【问题标题】:Performing advanced http requests in rxjs在 rxjs 中执行高级 http 请求
【发布时间】:2016-10-31 14:06:13
【问题描述】:

我有以下物品:

class Question {
    idQuestion: string;
    question: string;
    typeQuestion: string;
}

class Answer {
    idAnswer: string;
    idQuestion: string;
    answer: string;
}

class Option {
    idOption: string;
    idQuestion: string;
    option;
}

我想填充以下对象:

class QuestionOptionsAnswer {
    question: Question;
    answer: Answer;
    options: Option[];
}

现在,我对每种对象都有一个服务,所以我们可以用以下方式来说明它:

questionService.getQuestions();
answerService.getAnswers();
optionService.getOptions();

要填充 questionoptionsanswer 对象,我执行了嵌套请求:

questionService.getQuestions()
    .subscribe(
        answerService.getAnswers()
           .subscribe(
               optionService.getOptions()
                  .subscribe();
           )
    )

我可以正确填充questionoptionsanswer 对象,但速度很慢,所以我认为我的做法很糟糕。拥有questionoptionsanswer 背后的想法是使用 angular2 指令以一种简单的方式呈现html

我读到了flatMapswitchMapforkJoin,但我不太确定如何使用它们。

加载这些数据的好方法是什么?

questionoptionsanswer 将有一个问题对象、一个与之关联的答案,以及取决于typeQuestion 的可能选项,即:选择、单选、多个等。

【问题讨论】:

  • 真正的问题是您是否需要按此顺序调用请求。换句话说,一个 HTTP 请求的响应会影响下一个 HTTP 请求吗?
  • 不是独立的。答案和选项取决于每个问题,换句话说:每个问题都有一个答案和选项(取决于typeQuestion

标签: angular typescript rxjs rxjs5


【解决方案1】:

因此您需要调用第一个请求并等待其响应,然后同时调用另外两个请求(用于选项和答案)。

因为我想知道两个响应何时准备好,我将使用 Observable.forkJoin() 运算符,它在完成时发出一个包含源 Observables 的所有值的单个数组,然后将数据添加到 qoa 变量中订阅时传递给观察者。

concat()concatMap() 这样的操作符可以按顺序进行多次 HTTP 调用,但当您需要创建多个 Observable 来构造一个要发出的大型响应时(在您的情况下为 QuestionOptionsAnswer),它就不是很有用了。

我还使用Observable.of(...) 来模拟HTTP 请求。我不知道你的用例是什么,所以你可能不会使用Observable.create() 而是使用Subject

function getQOA() {
    return Observable.create(observer => {

        Observable.of({ question_id: '1' }).subscribe(response => {
            var qoa = new QuestionOptionsAnswer();
            let question = new Question();
            question.idQuestion = response.question_id;

            qoa.question = question;

            let obs1 = Observable.of({ answer_id: '1', answer: 'bla' });
            let obs2 = Observable.of([{ option_id: '1', option: 'ble' }]);

            Observable.forkJoin(obs1, obs2).subscribe(responses => {
                let [answerResponse, optionsResponse] = responses;

                let answer = new Answer();
                answer.idAnswer = answerResponse.answer_id;
                answer.answer = answerResponse.answer;
                qoa.answer = answer;

                qoa.options = optionsResponse.map(o => {
                    let option = new Option();
                    option.idOption = o.option_id;
                    option.option = o.option;
                    return option;
                });

                observer.next(qoa);
            });
        });
    });
}

getQOA().subscribe(qoa => console.log(qoa));

打印到控制台:

QuestionOptionsAnswer {
  question: Question { idQuestion: '1' },
  answer: Answer { idAnswer: '1', answer: 'bla' },
  options: [ Option { idOption: '1', option: 'ble' } ] }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-12
    • 1970-01-01
    相关资源
    最近更新 更多