【问题标题】:Javascript map in map await for responses地图中的 Javascript 地图等待响应
【发布时间】:2018-11-25 10:37:33
【问题描述】:

我有很多问题。
每个问题都有一些答案,这些答案是要上传的一些文件。
一切都很顺利,而不是 API 调用没有等待 Promise.all 完成。

步骤如下:

  1. 通过问题数组映射,如果问题是image类型,则获取所有文件并尝试上传。

  2. 上传后解决上传中的所有承诺并添加对该问题的答案Promise.all();的结果

  3. 在所有问题的循环准备就绪后,进行 API 调用以保存到数据库中,该数据库现在不等待上传所有文件并解析该数组中的所有内容。

export function 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 调用?

【问题讨论】:

  • 在内部循环中,您正在执行await Promise.all(results)。在外循环上,你什么都不做!

标签: javascript react-native asynchronous promise async-await


【解决方案1】:

给你一个我很久以前写的代码的例子:

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

【讨论】:

  • 我没有考虑它,因为我的 .map() 没有返回一组承诺,但是将 .map() 包装在 Promise.all() 中有所帮助。
  • 是的。弄清楚这一点很痛苦。花了我一段时间和一些调试。
【解决方案2】:

使用Promise.all 在数组中等待承诺

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

【讨论】:

  • 在 Promise.all 中包装 .map() + 其他小的更改使其工作。
猜你喜欢
  • 1970-01-01
  • 2022-12-20
  • 2020-12-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多