#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. не могли бы вы уточнить в соответствии с моим кодом, пожалуйста, я обновил вопрос