在 rxjs 中执行高级 http 请求
Performing advanced http requests in rxjs
我有以下对象:
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
。
我阅读了 flatMap
、switchMap
、forkJoin
,但我不太确定如何使用它们。
哪种方法是加载此数据的好方法?
questionoptionsanswer
将有一个问题对象、一个与之关联的答案,以及它可能的选项,具体取决于 typeQuestion
,即:select、单选、多选等。
因此您需要调用第一个请求并等待其响应,然后同时调用其他两个请求(选项和答案)。
因为我想知道两个响应何时准备就绪,所以我将使用 Observable.forkJoin()
运算符,它在完成时发出一个包含源 Observable 的所有值的数组,然后将数据添加到 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' } ] }
我有以下对象:
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
。
我阅读了 flatMap
、switchMap
、forkJoin
,但我不太确定如何使用它们。
哪种方法是加载此数据的好方法?
questionoptionsanswer
将有一个问题对象、一个与之关联的答案,以及它可能的选项,具体取决于 typeQuestion
,即:select、单选、多选等。
因此您需要调用第一个请求并等待其响应,然后同时调用其他两个请求(选项和答案)。
因为我想知道两个响应何时准备就绪,所以我将使用 Observable.forkJoin()
运算符,它在完成时发出一个包含源 Observable 的所有值的数组,然后将数据添加到 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' } ] }