Как дождаться завершения метода публикации Angular - PullRequest
0 голосов
/ 27 мая 2020

Я работаю над системой проверки знаний, поэтому как администратор я могу создавать тесты. На странице, где я создаю тесты, я в первую очередь ввожу информацию о тесте и количество вопросов. Затем для каждого вопроса я ввожу количество ответов на этот вопрос и информацию о вопросе. Затем для каждого ответа я ввожу некоторую информацию, а затем нажимаю кнопку отправки.

Порядок действий должен быть следующим:

Опубликовать тест -> Опубликовать первый вопрос -> Опубликовать ответы на первые вопросы -> Отправьте второй вопрос и и т.д. c.

Итак, мне нужно дождаться создания первого вопроса, затем создать каждый ответ на этот вопрос и только затем создать второй вопрос и ответы на него.

Порядок очень важен и должен быть таким, как я написал.

Но у меня есть ошибка, мой порядок не работает так, как я хочу, потому что мои методы публикации работают асинхронно.

Например, если Я создаю 2 вопроса и 2 ответа на каждый вопрос, который мой заказ превращает в следующее:

Пост-тест завершен -> Опубликовать вопрос 2 завершен -> Опубликовать вопрос 1 завершен -> Опубликовать все ответы завершены

Итак Мне нужно знать, как дождаться завершения метода публикации.

Вот мой метод, в котором я отправляю им вопросы и ответы:

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++;
    };
  }

Ответы [ 3 ]

1 голос
/ 27 мая 2020

Вы можете объединить две наблюдаемые ... для получения данных ответа, когда оба уже ответили.

fetchData(): Observable<any[]> {
    return combineLatest(
        this.observable1$(),
        this.observable2$()
    );
}
1 голос
/ 27 мая 2020

Здесь вам нужно использовать 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();
1 голос
/ 27 мая 2020

Я считаю, что ваш лучший выбор, ПОКОЛЬКО ВАМ НЕ НУЖНО РАЗМЕЩАТЬ ПУЧКУ , вероятно, это что-то рекурсивное, например:

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);
        }
    });
}); }
...