简体   繁体   中英

How to return data from an async .map() function?

I am looking to return some data from an asynchronous.map() function. It's async due to the axios call being inside of it to return some data. I am trying to.map() through an array [] inside files.kitchen and then call axios to get the base64 of each image URL inside files.kitchen . I have tried logging the data using await due to the asynchronous behavior of my function. The await returns undefined each time. I know I am calling it right by using await. However, I could have a syntax error. I've studied each relative question on here and none of them have worked for me.

Here is my code.

  const getbase64Data = () => {
    files.kitchen
      ? files.kitchen.map(async (image, index) => {
          const response = await axios.get(image, {
            responseType: "arraybuffer",
          });
          const buffer = Buffer.from(response.data, "binary").toString(
            "base64"
          );
          const data =
            "data:" + response.headers["content-type"] + ";base64," + buffer;
          return data;
        })
      : null;
  };
  console.log(await getbase64Data());

Please let me know if I need to share anything else.

From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Arrow functions can have either a "concise body" or the usual "block body".

In a concise body, only an expression is specified, which becomes the implicit return value. In a block body, you must use an explicit return statement.

in your code:

const getbase64Data = () => {
    files.kitchen
      ? files.kitchen.map(async (image, index) => {
          const response = await axios.get(image, {
            responseType: "arraybuffer",
          });
          const buffer = Buffer.from(response.data, "binary").toString(
            "base64"
          );
          const data =
            "data:" + response.headers["content-type"] + ";base64," + buffer;
          return data;
        })
      : null;
  };
  console.log(await getbase64Data());

getBase64Data has a block body... to use implicit return you need to remove the outer braces...

const getbase64Data = () => 
    files.kitchen
      ? files.kitchen.map(async (image, index) => {
          const response = await axios.get(image, {
            responseType: "arraybuffer",
          });
          const buffer = Buffer.from(response.data, "binary").toString(
            "base64"
          );
          const data =
            "data:" + response.headers["content-type"] + ";base64," + buffer;
          return data;
        })
      : null;
  console.log(getbase64Data());

Or, simply add a return statement

const getbase64Data = () => {
    var returnArray = files.kitchen
      ? files.kitchen.map(async (image, index) => {
          const response = await axios.get(image, {
            responseType: "arraybuffer",
          });
          const buffer = Buffer.from(response.data, "binary").toString(
            "base64"
          );
          const data =
            "data:" + response.headers["content-type"] + ";base64," + buffer;
          return data;
        })
      : null;
    return returnArray;
  };
  console.log(getbase64Data());

As Patrick Robert pointed out in his comment, you need to add a return. If you then get an array full of Promises use Promise.all

I often use something like this:

const fetched = await Promise.all(kitchen.map(async (image, index) => {
            return axios.get(image, {
            responseType: "arraybuffer",
          });
}))
fetched.map(x => { /* do stuff with fetched stuff here */ })

Promise.all awaits evey Promise element in the array.

You can do something like this:

const getbase64Data = () => {
  if (files.kitchen) {
    return Promise.all(files.kitchen.map(async (image, index) => { //Promise.all ensures all the async code gets executed
      const response = await axios.get(image, {
         responseType: "arraybuffer",
      });
        const buffer = Buffer.from(response.data, "binary").toString(
          "base64"
        );
        const data =
          "data:" + response.headers["content-type"] + ";base64," + buffer;
          return data;
     }));
  }
  return null;
};
console.log(await getbase64Data());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM