等待for循环的完成

时间:2020-07-05 16:54:26

标签: javascript image for-loop callback filereader

我正在尝试编写一些React代码来处理客户端文件上传。我在前端处理图像的大小调整,因此需要使用FileReaderFile对象转换为base64,然后转换为Image来检查尺寸,通过回调函数。

回调中的所有console.log均已正确打印,但是console.log(thumbnail_map_value)的最终返回值未定义。我认为这与函数执行的顺序有关。首先调用console.log(thumbnail_map_value),然后调用console.log("Client code done execution");,然后调用console.log(output_url)中的forEach,这意味着await generate_image_thumbnails(file, secure_url)不会像我期望的那样先解析。是。有人知道如何首先解析await generate_image_thumbnails(file, secure_url)以便console.log(thumbnail_map_value)返回非空值吗?

这是我的代码供参考。

//1. First function
export const create_media_map = async function(file) {
  try {
    //Some other code

    //file is a File object which a client app has uploaded

    //Async call
    const res_obj = await request.post(url)
      .field('upload_preset', upload_preset)
      .field('file', file);
    const res_body = res_obj.body;
    const public_id = res_body.public_id;
    const secure_url = res_body.secure_url;
    const media_object = {};

    console.log(secure_url);

    let thumbnail_map_value;
    let media_tags_value = [];

    if (file_type.includes(MEDIA_IMAGE_TYPE)) {
      //{s,m,l}
      thumbnail_map_value = await generate_image_thumbnails(file, secure_url);
      console.log(thumbnail_map_value); //First print: return undefined

      // More logic with secure_url after this comment

    } else {
      //Logic for video format

    }

    //some other logic


  } catch (error) {
    console.log(`Error with function: ${create_media_map.name}`,error);
  }
}



//Second function
export const generate_image_thumbnails = async function(file, original_url) {
  const url_obj = {};

  const fr = new FileReader;

  fr.onload = async function() { // file is loaded
    const img = new Image;

    img.onload = function() {
      console.log(img.width);
      console.log(img.height);

      const width = img.width;
      const height = img.height;
      const decider = Math.min(width,height);

      const all_sizes = [64, 128, 256];
      all_sizes.forEach((size) => {
        if (decider > size) {

          //Parsing logic to determine a value to string_type

          const query_string = `w_${size},h_${size}`;
          const output_url = create_query_url(original_url, query_string);
          console.log(output_url)//3rd Prints out correctly
          console.log(string_type);//small,medium or large
          url_obj[string_type] = output_url;
        }
      });

      return url_obj; //Returning undefined
    };

    img.src = fr.result;
    console.log("Client code done execution");//2nd

  };

  fr.readAsDataURL(file);


}

//Third function
export const create_query_url = function(original_url, query_string) {
  const right_half_no_slash = original_url.split("upload/").pop();
  const left_half_with_slash = original_url.replace(right_half_no_slash,"");

  return `${left_half_with_slash}${query_string}/${right_half_no_slash}`;
}

0 个答案:

没有答案