Выполнение запросов api к массиву объектов с использованием async / await и Promise.all ()

Я создаю простое приложение для поиска книг, делаю первоначальный запрос api для получения массива объектов книги, затем мне нужно сделать запрос api для каждой отдельной книги, чтобы получить размеры. Когда яconsole.log исходный массив книг, к которым добавлены книжные объекты attribute('height'), но я считаю, что это потому, что массив обновляется после того, как я выполняю свои вызовы api. Тогда, когда яconsole.logмассив после того, как я делаю отдельные вызовы api, мне предоставляется массив обещаний. Последний раз, когда яPromise.all() множество обещаний они все возвращаются undefined. Я немного поигрался с async / await и был бы признателен за любые советы или отзывы, которые, по вашему мнению, помогут мне выяснить, как иметь возможность возвращать массив моих книг с атрибутом "height", который я добавляю в отдельный api звонки.

    
    searchBook = (event) => {
    event.preventDefault();
    axios
      .get(
        "https://www.googleapis.com/books/v1/volumes?q=" +
          this.state.searchField +
          "&key=" +
          this.state.apiKey
      )
      .then((data) => {
        //fill in missing attributes
        const cleanData = this.cleanData(data.data.items);

        //filter books for specific author
        const filterAuthor = this.filterAuthor(cleanData);

        //add height attribute to book
        const addHeight = this.addHeight(filterAuthor);

        console.log(filterAuthor); //returns array of book objects

        console.log(addHeight); //returns array of promises

        Promise.all(addHeight).then((data) => {
          console.log(data); //returns array of undefined
        });
        //this.setState({ books: addHeight }); 
      });
  };

  //add 'height' attribute to book objects
  addHeight = (data) => {
    const addHeight = data.map(async (book) => {
      await axios
        .get(
          "https://www.googleapis.com/books/v1/volumes/" +
            book.id +
            "?key=" +
            this.state.apiKey
        )
        .then((data) => {
          if (data.data.volumeInfo?.dimensions) {
            book["height"] =
              data.data.volumeInfo.dimensions.height.split(" ")[0] / 2.54; //convert cm to in
          } else {
            book["height"] = "0";
          }
          return book;
        });
    });
    return addHeight;
  };

1 ответ

TL; DR

На мой взгляд, вам нужно вернуть обещание (я имею в виду, что нужно вернуть axios

Ответ

Я думаю, что в объекте обещания нет возвращаемого значения. когда вы используетеasync/await в const addHeight = data.map(async (book)=> {...})этот обратный вызов не может ничего вернуть. Итак, когда вы вернете аксиомы, ваше обещание может получить правильные данные

пример

 addHeight = (data) => {
    const addHeight = data.map((book) => {
     return axios
        .get(
          "https://www.googleapis.com/books/v1/volumes/" +
            book.id +
            "?key=" +
            this.state.apiKey
        )
        .then((data) => {
          if (data.data.volumeInfo?.dimensions) {
            book["height"] =
              data.data.volumeInfo.dimensions.height.split(" ")[0] / 2.54;
          } else {
            book["height"] = "0";
          }
          return book;
        });
    });
    return addHeight;
  };
Другие вопросы по тегам