[英]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.