2017-01-07 10 views
2

Прежде чем я начну, позвольте мне сказать, что я новичок в Javascript и очень новых вызовов Вардар API, так что я, вероятно, сделать новобранец ошибку ...API-интерфейс Axios API возвращает объект Promise вместо результата?

У меня есть эта функция getObjects(), что означало карту над массив и вернуть данные из вызова API Axios. Функция вызова и отображения API работает, но я получаю объект Promise вместо данных, которые я пытаюсь получить.

Я полагаю, что это потому, что данные возвращаются до того, как есть достаточно времени, чтобы на самом деле получить его, но не знаете, как исправить? Я попробовал .setTimeout(), но это, похоже, не сработало.

getObjects() { 
    let newsItems = this.state.arrayofids.map((index) => { 
     let resultOfIndex = axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${index}.json`).then((res) => { 
      let data = res.data; 
      //console.log(data.by); // this prints the correct byline, but 
           // all the bylines are printed after 
           // the console.log below... 
      if (!data.hasOwnProperty('text')) return data; 
     }); /// end of axios request 
    return resultOfIndex; 
    }); /// end of map 
    /// ideally this would end in an array of response objects but instead i'm getting an array of promises... 
    console.log(newsItems); 
    } 

(Лишние символы разлета в пользу моего текстового редактора.)

Here's a link to a codepen with the issue - открыть консоль, чтобы увидеть проблему. Это проект React, но я не думаю, что это проблема React. EDIT: Codepen Ссылка на рабочий раствор с помощью axios.all как предложено ниже

Спасибо!

EDIT: Вот мое рабочее решение.

getObjects() { 
    let axiosArr = []; 
    axios.all(this.state.arrayofids.map((id) => { 
     return axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${id}.json`) 
    })).then((res) => { 
     for (let i = 0; i < this.state.arrayofids.length; i++) { 
     axiosArr.push(<li key={i} data-url={res[i].data.url} onClick={(e) => this.displayTheNews(e)}>{res[i].data.title}</li>); 
     } 
     if (axiosArr.length == this.state.arrayofids.length) { 
     this.setState({arrayofdata: axiosArr}); 
     console.log('state is set!'); 
     } 
    }) 
} 
+1

Не специалист, но я использовал его на некоторое время. Я уверен, что он возвращает только обещания, так как есть функция 'axios.all'. Вы должны будете выработать логику внутри тогда, и я предлагаю использовать эквивалент this.setState или redux. На самом деле, возможно, вы захотите взглянуть на 'axios.all' вместо этого сопоставления. –

+0

@ A.Lau О, отлично, это определенно поставило меня на правильный путь. Спасибо. – JSilv

+0

Положим это как ответ тогда –

ответ

1

axios.all функция должна быть более подходящим к вашему текущему сценарию.

1

Ваш console.log выполняется моментально, а не ждет завершения запросов, так как они не являются синхронными. Вы должны дождаться всех ответов до вас console.log.

ВАРИАНТ 1 (твердый путь): заменить вашу console.log с

newsItems.forEach((promise, index) => { 
    promise.then((object)=>{ 
    newsItems[index] = object 
    if (index+1 == newsItems.length) { 
     console.log(newsItems) 
    } 
    }) 
}) 


ВАРИАНТ 2 (лучший способ): использованием axios.all

getObjects() { 
    axios.all(this.state.arrayofids.map((id) => { 
     return axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${id}.json`) 
    })).then((res) => { 
     console.log(res) 
    }) 
    } 

, кстати, я бы определенно рекомендую изменения

this.state.arrayofids.map((index) => { 
     let resultOfIndex = axios.get(`https:\/\/hacker-news.firebaseio.com/v0/item/${index}.json`)... 

называться id вместо index