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