асинхронное ожидание не работает должным образом

#javascript #api #async-await #promise

Вопрос:

Поэтому я показываю посты в Instagram в своем клиентском приложении. Instagram не позволяет клиентским приложениям, запущенным в браузере, напрямую запрашивать его API. Поэтому я создал node.js сервер для получения URL-адресов изображений преобразует их в формат, закодированный в base64, и передает эти выходные данные в мое клиентское приложение.

Вот мой серверный код. Вы можете видеть, что я извлекаю все сообщения instagram, соответствующие указанному значению переменной хэштега. Я знаю, что этот запрос выполняется успешно. В теле ответа каждое сообщение (я называю их «крайними»по соглашению API Instagram) содержит вложенный параметр, называемый thumbnail_src. Это URL-адрес, указывающий на изображение. В моей функции карты я передаю этот URL-адрес во вторую функцию под названием convertURLToBase64, которая должна выполнять то, что указано в имени функции.

Однако мой ответ пуст. Что происходит? Как мне это исправить? асинхронность/ожидание и обещания сложны. Спасибо

 async function getHashTaggedPosts(hashtag) {  url = "https://www.instagram.com/explore/tags/"   hashtag   "/?__a=1";  return await axios.get(url, { headers: { Authorization: AuthStr } }).then(  async (response) =gt; {  let edges = response.data.graphql.hashtag.edge_hashtag_to_media.edges;  updatedEdges = edges.map(async (edge) =gt; {  edge.imageBase64 = await convertURLToBase64(edge.node.thumbnail_src);  return edge;  })  console.log('updatedEdges: '   updatedEdges);  return updatedEdges;  },  (error) =gt; {  console.log("error: "   error.message);  }  ); }  async function convertURLToBase64(url) {  console.log('converting URL '   url   ' to base64');  await request.get(url, async function (error, response, body) {  if (!error amp;amp; response.statusCode == 200) {  console.log('there was no error receiving image');  data = "data:"   response.headers["content-type"]   ";base64,"   Buffer.from(body).toString('base64');  // console.log(data);  return data;  }  }); }  

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

1. await берет обещание и решает его. Но вы уже решили эту проблему, позвонив then . Вы объединяете два разных асинхронных паттерна, и они сталкиваются. Выберите один шаблон (ждите везде или затем везде), и это может помочь в отладке. (Законно сочетать эти два шаблона, но вы должны быть осторожны в том, как вы это делаете.)

Ответ №1:

С обратными вызовами, обещаниями ansyc/await, вы смешиваете три различных метода обработки кода asyc, что всегда не очень хорошая идея.

Как уже указывалось, в getHashTaggedPosts вас смешиваются await и .then в одном операторе, который я бы переписал, чтобы придерживаться одного единственного синтаксиса.

Кроме того, вы используете функцию массива .map с асинхронным обратным вызовом, что означает, что она вернет обещания, а не фактические значения, которые вы ожидаете. Здесь вам также нужно переписать эту часть. Если вы хотите придерживаться этой .map функции, вы можете использовать Promise.all .

Затем convertURLToBase64 вы ожидаете request.get метод, который, по-видимому, использует обратный вызов, поэтому он не вернет обещание, которого вы можете ждать. Вместо этого вы возвращаетесь из функции обратного вызова с return data; помощью, но это нигде не будет получено. Как правило, никогда ничего не возвращайте с обратного вызова.

Я не могу проверить ваш код, но попробуйте что-нибудь более похожее на это:

 async function getHashTaggedPosts(hashtag) {  try {  url = "https://www.instagram.com/explore/tags/"   hashtag   "/?__a=1";  const response = await axios.get(url, {  headers: { Authorization: AuthStr },  });  const edges = response.data.graphql.hashtag.edge_hashtag_to_media.edges;  const updatedEdges = await Promise.all(  edges.map(async (edge) =gt; {  edge.imageBase64 = await convertURLToBase64(edge.node.thumbnail_src);  return edge;  })  );  console.log("updatedEdges: "   updatedEdges);  return updatedEdges;  } catch (error) {  console.log("error: "   error.message);  }  }    function convertURLToBase64(url) {  console.log("converting URL "   url   " to base64");  return new Promise((res, rej) =gt; {  request.get(url, function (error, response, body) {  if (error || response.statusCode != 200) {  rej("Ups!");  return;  }  console.log("there was no error receiving image");  data =  "data:"    response.headers["content-type"]    ";base64,"    Buffer.from(body).toString("base64");  // console.log(data);  res(data);  });  });  }