Как вернуть данные из функции async .map()?

#javascript #node.js #asynchronous

#javascript #node.js #асинхронный

Вопрос:

Я хочу вернуть некоторые данные из функции asynchronous .map(). Это асинхронно из-за того, что axios внутри нее выполняется вызов для возврата некоторых данных. Я пытаюсь .map() через array [] inside files.kitchen , а затем вызываю axios, чтобы получить base64 для каждого URL-адреса изображения внутри files.kitchen . Я попытался записать данные с помощью await из-за асинхронного поведения моей функции. Ожидание возвращается undefined каждый раз. Я знаю, что правильно вызываю это, используя await. Однако у меня могла быть синтаксическая ошибка. Я изучил каждый соответствующий вопрос здесь, и ни один из них не сработал для меня.

Вот мой код.

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

Пожалуйста, дайте мне знать, если мне нужно поделиться чем-нибудь еще.

Комментарии:

1. В return вашей getbase64Data() функции этого нет.

Ответ №1:

Откуда:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Функции со стрелками могут иметь либо «краткое тело», либо обычное «тело блока».

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

в вашем коде:

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

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

Или просто добавьте оператор return

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

Комментарии:

1. Вы были правы, как и PLASMA chicken. Неявный возврат помог мне. Возвращением для этого был массив обещаний. Затем я использовал Promise.all()

2. Обязательно отметьте этот ответ как принятый, чтобы вопрос отображался как решенный, спасибо!

Ответ №2:

Как указал Патрик Роберт в своем комментарии, вам нужно добавить возврат. Если затем вы получите массив, полный обещаний, используйте Promise.all

Я часто использую что-то вроде этого:

 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 в массиве.

Комментарии:

1. Я смог использовать Promise.все просто отлично, вместе с ответом DynasticSponge о неявном возврате. Приветствия

Ответ №3:

Вы можете сделать что-то вроде этого:

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