Карта Javascript в карте ждут ответов - PullRequest
0 голосов
/ 25 ноября 2018

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

Ниже приведены шаги:

  1. отобразить массив вопросов, если вопрос относится к типу «изображение», получите все файлы и попытайтесь загрузить их.
  2. после загрузки разрешите все обещания из загрузки и добавьте ответ на этот вопрос в результате Promise.all ();
  3. После завершения цикла по всем вопросам выполните вызов API для сохранения в БД, котораятеперь не ждет загрузки всех файлов и разрешения всего в этом массиве.

функция экспорта sendReview (taskId, companyId, questions, navigation) {return async (dispatch) => {

dispatch(actions.sendReview.pending());
try {
  let user = await getUser();
  user  = JSON.parse(user);

  questions.map(async(question) => {
    if(question.type === 'image'){
      let images = question.answer;
      if(images.length > 0){
        const results = images.map(async (image) => {
          return await imageApi.upload(image).then(res => {
            return res.url;
          });
        });
        question.answer = await Promise.all(results).then((completed) => {
             return completed
        });
      }
    }
  });

  const data = await tasksApi.sendReview({
    task_id: taskId,
    company_id: companyId,
    user_id: user.id,
    questions: JSON.stringify(questions)
  });
  if(data.status === 201){
    markAsCompleted(taskId);
    navigation.navigate('MyTasks');
    dispatch(actions.sendReview.success({}));
  }else{
    dispatch(actions.sendReview.error());
  }
} catch (err) {
  dispatch(actions.sendReview.error(err));
}

};}

Вот используемая функция.

Как я могу убедиться, что все элементы в .map () готовы и только после этого сделать вызов API?

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

, чтобы дать вам пример из кода, который я сделал довольно давно:

await Promise.all((await readdir(repoPath, "utf8")).map(async file => {
  if (!/\.mjs$/.test(file)) return;
  const filePath = `${repoPath}/${file}`;
  log(`importing "${file}"`);

  const module = await import(filePath);

  const meta = {
    repository,
    file,
    filePath,
    description: module.description || {}
  };

  module.default((...args) => createModule(meta, ...args));
}));

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

Promise.all() поможет вам в этом.

, поэтому в вашем случае все, что вам нужно сделать, это изменить:

questions.map(async(question) => {
  if(question.type === 'image'){
    let images = question.answer;
    if(images.length > 0){
      const results = images.map(async (image) => {
        return await imageApi.upload(image).then(res => {
          return res.url;
        });
      });
      question.answer = await Promise.all(results).then((completed) => {
        return completed
      });
    }
  }
});

следующим образом:

await Promise.all(questions.map(async(question) => {
  if(question.type === 'image'){
    let images = question.answer;
    if(images.length > 0){
      const results = await Promise.all(images.map(async (image) => {
        return await imageApi.upload(image).then(res => {
          return res.url;
        });
      }));
      question.answer = results.then((completed) => {
        return completed
      });
    }
  }
}));
0 голосов
/ 25 ноября 2018

Используйте Promise.all для ожидания обещаний в массиве

Promise.all(questions.map(...))

...