Как выполнять асинхронные вызовы api в цикле и условных операторах в react js?

#javascript #arrays #reactjs

Вопрос:

 [
  {
    description: "question value1",
    subjectId: "",
    classId: "",
    image:"",
    answers: [{ description: "option value", isCorrect: false },
    { description: "option value", isCorrect: true }
    ],
  },
  {
    description: "question value2",
    subjectId: "",
    classId: "",
    answers: [{ description: "option value", isCorrect: false },
    { description: "option value", isCorrect: true }
    ],
  },
]
 

У меня есть что-то вроде этого, и теперь мне нужно сделать почтовый вызов api для каждого вопроса, чтобы, как только вопрос будет создан, я вернул идентификатор вопроса, а затем я могу использовать этот идентификатор для создания опций для этого вопроса, и если у него есть изображение, которое тоже загружается, и мне нужно подождать, пока каждый из них закончит, как я могу это сделать, я действительно плохо асинхронно программирую, есть API sperate для создания вопроса, создающие опцию для вопроса, загружающего изображение для вопроса
Это то, что я пробовал до сих пор, но по какой-то причине это неправильный idk

     async mapCreatedQuestions(questionId) {
    let token = getCookie(process.env.token);
    let formData = new FormData();
    formData.append("QuestionId", questionId);
    formData.append("QuizId", this.state.quizId);
   await axios
      .post(`api to create a association if question already exists`, formData, {
        headers: {
          authorization: `${TOKEN_TYPE}${token}`,
        },
      })
      .then((response) => {})
      .catch((err) => {
        console.log("Error !!!.. association");
        console.log(err);
        this.setState({ loading: false });
      });
  }
  async createOptions(question, questionId) {
    let token = getCookie(process.env.token);
    question.answers.map((option, index) => {
      //options uploaded from here
      console.log("this options are for the question", option);
      if (option.description.length > 0) {
        let formData = new FormData();
        formData.append("Description", option.description);
        formData.append("QuestionId", questionId);
        formData.append("IsCorrect", option.isCorrect);
        axios
          .post(`api to add answers(options)`, formData, {
            headers: {
              authorization: `${TOKEN_TYPE}${token}`,
            },
          })
          .then((response) => {
            console.log("option created", response);
          })
          .catch((err) => {
            console.log("Error !!!.. In options");
            console.log(err);
            this.setState({ loading: false });
          });
      }
    });
  }
  async questionImageUpload(questionPicture, questionId) {
    let token = getCookie(process.env.token);
    //upload the picture of the question

    let formData = new FormData();
    formData.append("ImageTitle", "quizImage"   questionId);
    formData.append("QuestionId", questionId);
    formData.append("Image", questionPicture);
  await  axios
      .post(`api to upload image`, formData, {
        headers: {
          authorization: `${TOKEN_TYPE}${token}`,
        },
      })
      .then((response) => {
        console.log("image uploaded successfully ", response);
      })
      .catch((err) => {
        console.log(" image upload failed err", err);
        this.setState({ loading: false });
      });
  }
 async createEachQuestion (question){
   let formData = new FormData();
   formData.append("Description", question.description);
   formData.append("QuestionTypeId", question.questionTypeId);
   formData.append("SubjectId", question.subjectId);
  await axios
     .post(`apitocreatequestion`, formData, {
       headers: {
         authorization: `${TOKEN_TYPE}${token}`,
       },
     })
     .then((response) => {
       this.setState({ questionId: response.data.result });
       let questionId = response.data.resu<
       if (question.questionPicture.toString().length > 0) {
        this.questionImageUpload(question.questionPicture, questionId);
       }
     })
     .catch((err) => {
       console.log("error in question creationn", err);
     });
      await this.createOptions(question,questionId);
     await this.mapCreatedQuestions(questionId);

 } 
 async mapEachQuestion (){
  console.log("this question will be mapped not created", question);
  let formData = new FormData();
  formData.append("QuestionId", question.questionId);
  formData.append("QuizId", this.state.quizId);
 await axios
    .post(`apitoassociatequestionandquiz`, formData, {
      headers: {
        authorization: `${TOKEN_TYPE}${token}`,
      },
    })
    .then((response) => {
      console.log("question asssociated", response);
    })
    .catch((err) => {
      console.log("Error !!!.. association");
      console.log(err);
      this.setState({ loading: false });
    });
 }
  async createQuestion() {
    let token = getCookie(process.env.token);
    this.state.questionList.map((question, index) => {
      if (question.hasOwnProperty("questionId")) {
        //map the existing question id to quiz
        this.mapEachQuestion (question)
      } else {
        this.createEachQuestion (question)
      }
    });
  }

  async createQuiz(quiz) {
    await this.setQuestionList;
    await this.sendQuiz;
    this.setState({ loading: true });
    let formData = new FormData();
    console.log("quiz", quiz);
    console.log("this.state.questionList", this.state.questionList);
    let id = getCookie(process.env.iId);
    formData.append("Description", quiz.Description);
    formData.append("Title", quiz.Title);
    formData.append("TimeinMinute", quiz.TimeInMinute);
    let token = getCookie(process.env.token);
    await axios
      .post(`apitocreatequiz`, formData, {
        headers: {
          authorization: `${TOKEN_TYPE}${token}`,
        },
      })
      .then((response) => {
        console.log("quiz created successfully. Response =>", response);
        //setQuizId in state
        this.setState({ quizId: response.data.result });
        
      })
      .catch((err) => {
        console.log("Error !!!.. when creating the quiz");
        console.log(err);
        this.setState({loading:false});
      });
      await this.createQuestion;
      this.setState({loading: false});
  }
 

Комментарии:

1. У вас проблемы с рендерингом, цикличностью или чем-то еще? Пожалуйста, расскажите подробнее о проблеме, поделитесь своим кодом и другими вещами, которые могут помочь

2. Что вы пробовали до сих пор, пожалуйста, поделитесь этим, чтобы кто-то мог помочь.

3. да, я отредактировал сообщение, может ли кто-нибудь помочь

Ответ №1:

Вызовы API-это обещание, что данные будут возвращены в какой-то момент.

К счастью, асинхронные процессы в последнее время стали намного проще в обращении. Вы можете использовать Promise.all для захвата данных, как только они будут разрешены.

Ваши данные уже находятся в массиве, поэтому это становится намного проще.

В этом первом примере вы можете использовать API выборки, чтобы получить данные, а затем собрать их.

 function mockApi(n) {
  return new Promise((res, rej) => {
    setTimeout(() => res(n), 2000);
  });
}

const input = [1, 2, 3, 4];

function getData(input) {

  // Instead of mockApi(el) use `fetch(url)`
  const promises = input.map(el => mockApi(el));
  Promise.all(promises).then(data => {
    console.log(data);
  });
}

getData(input); 

В этом примере вы можете использовать async/await :

 function mockApi(n) {
  return new Promise((res, rej) => {
    setTimeout(() => res(n), 2000);
  });
}

const input = [1, 2, 3, 4];

async function getData(input) {
  const data = input.map(el => mockApi(el));
  const output = await Promise.all(data);
  console.log(output);
}

getData(input);
 

Комментарии:

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