Отправка/ожидание ответа API на массив

Я пытаюсь создать массив URL-адресов, массив называется «предложения». До сих пор я видел, что вы должны использовать useState, если хотите поместить ответ API в массив. Это то, что я пробовал до сих пор.

  const [sentences, setSentences] = useState([]);

  const getOpenAIResponse = () => {
    for (var i = 0; i < 6; i++) {
      openai.createImage({
        prompt: prompts[i],
        n: 1,
        size: "256x256",
      }).then((response) => {
        setSentences(response.data.data[0].url)
        console.info(sentences)
      })
    }
  };

Проблема заключается в том, что предложения просто обновляются со следующим сгенерированным ответом URL. Использование setSentences.push(...) не работает. Есть что-нибудь, что бы вы порекомендовали?

Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
Как использовать API парсинга квитанций с помощью JavaScript за 5 минут?
В этом руководстве вы узнаете, как использовать API парсинга квитанций за 5 минут с помощью JavaScript. Eden AI предоставляет простой и удобный для...
Хук useOnClickOutside в ReactJS
Хук useOnClickOutside в ReactJS
Как разработчик ReactJS, вы, возможно, сталкивались с ситуацией, когда вам нужно закрыть модальное или выпадающее меню, когда кто-то щелкает за его...
Хуки (часть-2) - useEffect
Хуки (часть-2) - useEffect
Хук useEffect - один из самых мощных и универсальных инструментов в арсенале разработчика React. Он позволяет вам управлять побочными эффектами в...
Простое руководство по тестированию взаимодействия с пользователем с помощью библиотеки тестирования React
Простое руководство по тестированию взаимодействия с пользователем с помощью библиотеки тестирования React
В предыдущем посте я показал вам на примерах, как писать базовые тесты в React. Важнейшей частью пользовательского интерфейса приложений является...
Как конвертировать HTML в PDF с помощью jsPDF
Как конвертировать HTML в PDF с помощью jsPDF
В этой статье мы рассмотрим, как конвертировать HTML в PDF с помощью jsPDF. Здесь мы узнаем, как конвертировать HTML в PDF с помощью javascript.
Создайте титры как в звездных войнах с помощью CSS и Javascript
Создайте титры как в звездных войнах с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
1
0
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Новые заметки

Похоже, я не учел, что при запуске getOpenAIResponse вы вызываете openai.createImage 6 раз, и при каждом запуске вы получаете URL, который нужно добавить в sentences. Вот некоторый обновленный код, который должен работать для вас:

const getOpenAIResponse = () => {
  imagePromises = [];

  // Collect all image promises in an array
  for (var i = 0; i < 6; i++) {
    imagePromises.push(
      openai.createImage({
        prompt: prompts[i],
        n: 1,
        size: "256x256",
      })
    );
  }

  // Do something once all promises resolve
  Promise.all(imagePromises)
    .then((responses) => {
      setSentences([
        // Keep current list of sentences
        ...sentences,

        // Add new sentences to old list of sentences
        ...responses.map(response => response.data.data[0].url),
      ]);
    });
};

Старые заметки

Там, где у вас есть setSentences(response.data.data[0].url), это заменит ваш существующий МАССИВ предложений только одним конкретным предложением, возвращаемым openai.createImage. Что вы хотите, так это взять возвращенный URL-адрес, добавить его в свой массив sentences, а затем обновить состояние.

Для этого замените строку setSentences на setSentences(sentences.concat(response.data.data[0].url)).

Я не понимаю, как вы использовали .push раньше, но .push не «возвращает» обновленный массив, а .concat делает!

Вы можете увидеть это в консоли разработчика Chrome с помощью этих двух тестов:

// This returns 4 which is the size of the array!
[1,2,3].push(4);

// These return [1,2,3,4] which is the new array, with the added new element at the end
[1,2,3].concat(4);
[1,2,3].concat([4]);

Разве аргумент не должен быть заключен в массив?

CherryDT 18.11.2022 18:29

@CherryDT не нужен, если вы добавляете только 1 элемент в массив sentences, вам не нужно оборачивать response.data.data[0].url в массив

Blundering Philosopher 18.11.2022 18:29

Он будет вести себя неожиданно, если этот элемент сам по себе является массивом, поэтому лучше изучить его последовательно с самого начала, чтобы избежать будущих сюрпризов. В качестве альтернативы я бы рекомендовал (возможно, более чистый) синтаксис [...sentences, response.data.data[0].url].

CherryDT 18.11.2022 18:31

@CherryDT Вы уверены, что он будет вести себя неожиданно? Если я это сделаю [1,2].concat([3]), я не увижу новый массив как [1,2,[3]], я увижу [1,2,3]

Blundering Philosopher 18.11.2022 18:32

Вот именно это и неожиданно. Если вы узнаете, что «a.concat(x) будет добавлять x к массиву», вы будете удивлены случаем, который вы только что показали, где x было бы [3], а не 3, но в массив было добавлено 3. Я поклонник четко определенных универсальных инструментов, чтобы узнать, где вам не придется помнить о пограничных случаях позже (примером подобной проблемы может быть new Array(...), где передача одного аргумента, который оказывается числом, приведет к к совершенно другому поведению, чем во всех других случаях - и это даже причина, по которой он устарел). Мои два цента.

CherryDT 18.11.2022 18:35

Ааа, теперь я понимаю, что вы имеете в виду @CherryDT - я думаю, я привык к этому, так что это больше не «неожиданно», но, как вы упомянули, может быть неплохо сделать код очень явным, чтобы вы знали, как иметь дело с x vs [x] имеет разное поведение. Однако в этом конкретном случае, я думаю, ситуация достаточно ясна в обоих решениях, что новый URL-адрес будет добавлен в массив - если .url начинает быть массивом URL-адресов, его следует переименовать .urls, чтобы указать, что

Blundering Philosopher 18.11.2022 18:40

Спасибо. Почему-то сохраняется та же проблема. Предложение [0] изменяется 6 раз, и как только я снова нажимаю кнопку, которая активирует ответ API, я получаю предложение [1], которое также регенерируется 6 раз. Кажется, он не дает мне массив URL-адресов, как я хочу.

ati 18.11.2022 18:59

@ati Хорошо, когда вы нажимаете кнопку, это вызывает getOpenAIResponse, верно? Похоже, проблема, которую мы не решили, заключается в том, что вы запускаете openai.createImage 6 раз для каждого нажатия кнопки, и каждый раз вы ожидаете, что 6 новых URL-адресов вернутся и будут добавлены в sentences, это правильно?

Blundering Philosopher 18.11.2022 19:10

@ati взгляните на обновленный ответ, я учел тот факт, что у вас есть несколько обещаний, которые необходимо разрешить, прежде чем добавлять полученные предложения в состояние массива!

Blundering Philosopher 18.11.2022 19:16

Хм, но теперь я считаю, что вам действительно нужен массив в вашем последнем ответе :) Верно? Потому что setSentences должен иметь только один аргумент, новое значение, а не несколько. Так и должно быть setSentences([...sentences, ...newStuff])

CherryDT 18.11.2022 19:35

Спасибо, я только что попробовал, и я получаю букву h для предложений [0], а затем 6 ошибок изображения. @BlunderingPhilosopher @cherryDT

ati 18.11.2022 19:51

@CherryDT выглядит так, как будто вы профессиональный QAer 😅 Клянусь, я добавил это (не смотрите на историю редактирования этого ответа 🙏) - также Ати - теперь это должно работать - извините за небольшую опечатку

Blundering Philosopher 18.11.2022 19:57

@ati просто чтобы вы знали, я просто предполагаю, что response.data.data[0].url - это правильный способ получить URL-адрес изображения из вашего ответа API - вы можете трижды проверить его точность: D

Blundering Philosopher 18.11.2022 20:02

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

setSentences([...sentences, response.data.data[0].url])

Вы также можете использовать метод concat, чтобы добавить новый URL-адрес в массив.

setSentences(sentences.concat(response.data.data[0].url))

Спасибо, но почему-то такая же проблема. предложения [0] меняются 6 раз, и как только я снова нажимаю кнопку, которая активирует ответ API, я получаю предложения [1], которые также регенерируются 6 раз. Кажется, он не дает мне массив URL-адресов, как я хочу.

ati 18.11.2022 19:00

Другие вопросы по теме