[英]How to wait until post method finished Angular
我正在开发知识测试系统,因此作为管理员,我可以创建测试。 在我创建测试的页面上,首先我输入有关测试和问题计数的信息。 然后对于每个问题,我都会输入该问题的答案计数和有关问题的信息。 然后对于每个答案,我都会输入一些信息,然后单击提交按钮。
动作顺序必须如下:
发布测试->发布第一个问题->发布第一个问题的答案->发布第二个问题等。
所以我需要等到第一个问题被创建,然后为这个问题创建每个答案,然后才为它创建第二个问题和答案。
顺序非常重要,必须像我写的那样。
但我有一个错误,我的订单没有按我想要的方式工作,因为我的 post 方法是异步工作的。
例如,如果我为每个问题创建 2 个问题和 2 个答案,我的订单将变为:
发布测试完成 -> 发布问题 2 完成 -> 发布问题 1 完成 -> 发布所有答案完成
所以我需要知道,如何等到 post 方法完成。
这是我为他们发布问题和答案的方法:
for(let item of this.sas){// sas is type Map<Question, Answer[]>
// get question info
let q = document.getElementById(`q_${ii+1}`) as HTMLInputElement;
let t = document.getElementById(`t_${ii+1}`) as HTMLInputElement;
let isSin = true;
if(t.checked){
isSin = false;
}
let question = new Question();
question.Content = q.value;
question.IsSingle = isSin;
//
// get answers for this question
let answers = [];
for(let j of item[1]){
let isCorrect = document.getElementById(`a_isCorrect_${ii}:${j}`) as unknown as HTMLInputElement;
let content = document.getElementById(`a_content_${ii}:${j}`) as unknown as HTMLInputElement;
let mark = document.getElementById(`a_mark_${ii}:${j}`) as unknown as HTMLInputElement;
let answer = new Answer();
answer.IsCorrect = isCorrect.checked;
answer.Content = content.value;
answer.Mark = Number(mark.value);
answers.push(answer);
j++;
}
//post question
this.questionService.createQuestion(question).subscribe(data=> {
console.log(`question ${question.Content} done`);
//
//post answers for question
from(answers).pipe(
map(answer => this.answerService.createAnswer(answer).subscribe(data => {
console.log(`answer ${answer} done` ) } ) )
).subscribe(s=> { console.log("done")});
//
});
ii++;
};
}
我相信你最好的选择,只要你不需要 POST A BUNCH ,可能是这样的递归:
function handleQuestion(item, index = 0) {
let q = document.getElementById(`q_${index+1}`) as HTMLInputElement;
let t = document.getElementById(`t_${index+1}`) as HTMLInputElement;
let isSin = true;
if(t.checked){
isSin = false;
}
let question = new Question();
question.Content = q.value;
question.IsSingle = isSin;
let answers = [];
for(let j of item){
let isCorrect = document.getElementById(`a_isCorrect_${index}:${j}`) as unknown as HTMLInputElement;
let content = document.getElementById(`a_content_${index}:${j}`) as unknown as HTMLInputElement;
let mark = document.getElementById(`a_mark_${index}:${j}`) as unknown as HTMLInputElement;
let answer = new Answer();
answer.IsCorrect = isCorrect.checked;
answer.Content = content.value;
answer.Mark = Number(mark.value);
answers.push(answer);
j++;
}
this.questionService.createQuestion(question).subscribe(data=> {
from(answers).pipe(
map(answer => this.answerService.createAnswer(answer).subscribe(data => {
console.log(`answer ${answer} done` ) } ) )
).subscribe(s=> {
index++;
if (this.sas[index]) {
handleQuestion(this.sas[index], index);
}
});
}); }
您可以结合两个 observables... 以在两者都已经响应时获得响应数据。
fetchData(): Observable<any[]> {
return combineLatest(
this.observable1$(),
this.observable2$()
);
}
你需要在这里使用concatMap
,它会逐步等待每次发射。
//post question
this.questionService.createQuestion(question).pipe(
// executes answers only when question emits.
concatMap(data=> {
console.log(`question ${question.Content} done`);
//
//post answers for question
return from(answers).pipe(
concatMap(answer => this.answerService.createAnswer(answer).pipe(
tap(data => console.log(`answer ${answer} done` ) ),
)),
finalize(() => console.log("done")),
);
}),
).subscribe();
如果你想要整件事:
let ii = 0;
from(this.sas).pipe(
contactMap(item => {
// get question info
let q = document.getElementById(`q_${ii+1}`) as HTMLInputElement;
let t = document.getElementById(`t_${ii+1}`) as HTMLInputElement;
let isSin = true;
if(t.checked){
isSin = false;
}
let question = new Question();
question.Content = q.value;
question.IsSingle = isSin;
//
// get answers for this question
let answers = [];
for(let j of item[1]){
let isCorrect = document.getElementById(`a_isCorrect_${ii}:${j}`) as unknown as HTMLInputElement;
let content = document.getElementById(`a_content_${ii}:${j}`) as unknown as HTMLInputElement;
let mark = document.getElementById(`a_mark_${ii}:${j}`) as unknown as HTMLInputElement;
let answer = new Answer();
answer.IsCorrect = isCorrect.checked;
answer.Content = content.value;
answer.Mark = Number(mark.value);
answers.push(answer);
j++;
}
ii++;
//post question
return this.questionService.createQuestion(question).pipe(
// executes answers only when question emits.
concatMap(data=> {
console.log(`question ${question.Content} done`);
//
//post answers for question
return from(answers).pipe(
concatMap(answer => this.answerService.createAnswer(answer).pipe(
tap(data => console.log(`answer ${answer} done` ) ),
)),
finalize(() => {
console.log("done");
),
);
}),
);
}),
finalize(() => {
// call done function here.
),
).subscribe();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.