попытка получить данные из строки массива, включающей адрес API

#javascript #json #reactjs

#javascript #json #reactjs

Вопрос:

Я хочу получить данные из массива, который включает в себя API внутри, проблема в том, что количество api внутри массива иногда отличается от других.

 {
"name": "CR90 corvette", 
"model": "CR90 corvette", 
"manufacturer": "Corellian Engineering Corporation", 
"cost_in_credits": "3500000", 
"length": "150", 
"max_atmosphering_speed": "950", 
"crew": "30-165", 
"passengers": "600", 
"cargo_capacity": "3000000", 
"consumables": "1 year", 
"hyperdrive_rating": "2.0", 
"MGLT": "60", 
"starship_class": "corvette", 
"pilots": [], 
"films": [
    "http://swapi.dev/api/films/1/", 
    "http://swapi.dev/api/films/3/", 
    "http://swapi.dev/api/films/6/"
], 
"created": "2014-12-10T14:20:33.369000Z", 
"edited": "2014-12-20T21:23:49.867000Z", 
"url": "http://swapi.dev/api/starships/2/"} 
  

В приведенном выше коде json поле Films — это массив, который я имею в виду, например, в этих данных Films содержит 3 данные в виде адресов API, в других данных у них есть 2 данные адресов API и так далее.

Мой вопрос в том, как я могу вызвать API внутри массива таким образом, и как я могу вызвать все адреса API внутри одновременно?

Спасибо, что нашли время прочитать это, слава.

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

1. что вы подразумеваете под вызовом? Вы имеете в виду асинхронный вызов?

2. Promise.all вероятно, это то, что вы хотите.

Ответ №1:

Есть много способов сделать это. Следующий код отправляет запросы на данные фильма в быстрой последовательности, а затем используется Promise.all для ожидания их возврата, прежде чем продолжить. Обратите внимание, что это Promise.all приведет к быстрому сбою, если один запрос выдает исключение. Используйте Promise#allSettled , если вы хотите замедлить работу.

 const data = { films: [ 'http://example.com/1', 'http://example.com/2', 'http://example.com/3' ]}
const { films: urls } = data
const promises = []

for(let url of urls)
  promises.push(fetch(url))

Promise.all(promises)
  .then((filmDetails) => {
    for(let details of filmDetails)
      console.log(filmDetails)
  })
  

Ответ №2:

Вы можете использовать async await amp; затем использовать fetch для выполнения вызова api.

 let data = {
  "name": "CR90 corvette",
  "model": "CR90 corvette",
  "manufacturer": "Corellian Engineering Corporation",
  "cost_in_credits": "3500000",
  "length": "150",
  "max_atmosphering_speed": "950",
  "crew": "30-165",
  "passengers": "600",
  "cargo_capacity": "3000000",
  "consumables": "1 year",
  "hyperdrive_rating": "2.0",
  "MGLT": "60",
  "starship_class": "corvette",
  "pilots": [],
  "films": [
    "https://swapi.dev/api/films/1/",
    "https://swapi.dev/api/films/3/",
    "https://swapi.dev/api/films/6/"
  ],
  "created": "2014-12-10T14:20:33.369000Z",
  "edited": "2014-12-20T21:23:49.867000Z",
  "url": "http://swapi.dev/api/starships/2/"
};

async function fncGetResult(arr) {
  let val = [];
  for (let i = 0; i < arr.length; i  ) {
    const res = await fetch(arr[i]).then(d => d.json()).then(d =>d);
    val.push(res)
  };
  return val;
}

fncGetResult(data.films).then((result) => {
  console.log(result)
})  

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

1. Это приведет к последовательному выполнению запросов, я думаю promise.all , что это гораздо лучший вариант для использования здесь, потому что каждый HTTP-запрос не зависит от других запросов.

2. я только что попробовал ваш код, и он работает, но затем я получаю сообщение об ошибке «Необработанное отклонение (TypeError): arr не определено», как я могу это исправить?

3. @brk я поместил свой полный код здесь codeshare.io/starship

4. @brk некоторый массив, содержащий адреса API

5. Попробуйте вызвать, как это axios.get( swapi.dev/api/starships/ $ {id}/ ).then((result) => { setDetail(result.data); fncGetResult(result.data.films) });

Ответ №3:

Вы можете использовать функцию map из пакета async.

Async — это служебный модуль, который предоставляет простые, мощные функции для работы с асинхронным JavaScript. Хотя изначально предназначался для использования с Node.js и устанавливаемый через npm i async, он также может быть использован непосредственно в браузере.

Первый параметр — это ваш массив, который вы можете удалить из своего объекта, второй — вызов вашего api или любой другой асинхронной функции (здесь я использую axios package , но вы можете вызвать api только с помощью собственного пакета узла http ), а третий — функция обратного вызова, которая может обеспечить вам проверку успешной работы.

 import async from 'async'
import axios from 'axios'

const obj = {
    name: "CR90 corvette", 
    films: [    
        "http://swapi.dev/api/films/1/",  
        "http://swapi.dev/api/films/3/", 
        "http://swapi.dev/api/films/6/"
    ]
}

const { films } = obj

const responses = async.map(
    films, 
    (url, callback) => {
        try {
            axios.get(url)
            callback(null, 'OK')
        } catch (error) {
            callback(error)
        }
    }, (error, result) => {
        if (error) {
            console.log(error)
        }
        console.log(result)
    }
)