2017-02-14 7 views
0

У меня изначально был только один URL-адрес для извлечения данных, и мое приложение работало безупречно. Но потом я понял, что мне нужно использовать два разных URL-адреса для получения данных, которые мне нужны. Поэтому я немного изменил код. Все почти то же самое, за исключением функции getData, где я использовал map для перебора списка URL-адресов и получения данных. Теперь мое приложение действительно глючит.Почему моя функция поиска так медленно + багги иногда?

Проблема:

Когда я искать серпантин, иногда никогда не штукатурки результата на странице. И сообщение "search for your favorite streamer!" не исчезает, хотя this.state.value сейчас НЕ равно ' '. Но когда я меняю вход, он получается из ниоткуда.

Иногда он не может отобразить данные, и я получаю вывод FinderResultContainer без данных. (Нет имени, нет img, нет офлайн/онлайн.)

Что здесь происходит? Я чувствую, что это потому, что я не использую методы жизненного цикла компонентов. Если да, то что именно мне нужно сделать? Я полный новичок, поэтому мне нужно какое-то руководство.

getData(value) { 
let streamerData = []; 
let streamerInfo = {}; 

let urls = ['https://wind-bow.gomix.me/twitch-api/streams/' + value, 'https://wind-bow.gomix.me/twitch-api/users/' + value]; 

urls.map(function(each, index) { 
    fetch(each).then((response) => 
    response.json() 
).then((streamer) => streamerData.push(streamer)).then(()=>streamerInfo[index]=streamerData[index]).then(()=>{if (index === urls.length-1){this.setState({streamer: streamerData})}})},this) 
} 

https://codepen.io/brood915/pen/OWQpmy

+0

, так как вы делаете два вызова ajax (я предполагаю, что они являются вызовами ajax), вы, вероятно, должны использовать функцию, которая ждет, когда все они ответят, прежде чем делать последнюю вещь. –

+0

Используйте обещания, потому что веб-API являются асинхронными по своей природе Попробуйте https://caolan.github.io/async/ library –

ответ

0

fetch является асинхронным и возвращает обещание, так что вы не знаете точно, когда это будет сделано. Вы можете использовать Promise.all(), чтобы ждать каждого обещания, которое необходимо решить, а затем работать с данными (обратите внимание, что все обещания будут выполняться в одно и то же время, поэтому, если у вас есть большой список URL-адресов, вы будете отправлять тонны запросов в секунду).

Редактировать: Я видел вашу ручку и упрощал код, это отлично работает для меня. Здесь нет пустого компонента. Обратите внимание, что вам только необходимо использовать then при возвращении обещаний.

getData(value, type) { 
    let urls = [ 
    'https://wind-bow.gomix.me/twitch-api/streams/' + value, 
    'https://wind-bow.gomix.me/twitch-api/users/' + value 
    ]; 

    const getJson = url => fetch(url).then(res => res.json()); 

    Promise.all(urls.map(getJson)) 
    .then(streamer => { 
     if (type === "search") { 
     this.setState({ streamer }); 
     console.log("searching") 
     } else { 
     console.log("displaying"); 
     this.getStreamer(streamer[0], streamer[1]); 
     } 
    }).catch(err => { 
     console.log('Something went wrong...') 
    }) 
} 
+0

Удивительно большое вам спасибо. Есть ли другой способ достичь того же? Я вижу, что это не поддерживает И.Е. – brood915

+0

Я попробовал Promise.all (urls.map (функция (каждый, индекс) { fetch (каждый). Then ((response) => response.json() ) .then ((стример) => streamerData.push (streamer)), затем (() => streamerInfo [index] = streamerData [index]). then (() => {if (index === urls.length-1) {this.setState ({streamer: streamerData })}})}, это)) } и он по-прежнему иногда делает пустой компонент .. hm .. – brood915

+0

Для поддержки IE8 вам необходимо [полипол.] (https://github.com/taylorhakes/promise- polyfill) Я немного очистил код и удалил ненужные переменные. – mallendeo