2016-10-18 2 views
0

У меня проблемы с истинным пониманием асинхронного поведения. Я звоню в японскую базу данных, но из-за асинхронного поведения мои вызовы находятся на шаг впереди входа пользователя. Например, пользователь вводит буквы G, и ответа не будет, пока пользователь не наберет Go. Затем мое приложение отправит запрос на поиск по букве G, когда пользователь исключает результаты для Go. Надеюсь, это имеет смысл.React Native Fetch asynchronous

Здесь я делаю свой асинхронный вызов.

sendData(){ 
     fetch('http://jisho.org/api/v1/search/words?keyword='+this.state.wordLookUp).then((dictionary) => { 

       return dictionary.json(); 
      }).then((dictionary) => { 
       console.log(dictionary); 
       this.setState({ 
        dictionary:dictionary.data, 
        loading:false 
       }) 

      }).done((dictionary)=>{ 
       console.log(this.state.dictionary); 


      }); 


    } 

Прямо здесь, где я отображения результатов пользователю

renderList(){ 
    if(!this.state.wordLookUp.length){ 
     this.state.dictionary = null; 
    } 

    if(!this.state.dictionary){  
     return(
     <View> 
     <Text>loading</Text> 
     </View> 
     ) 
    }else{ 

    return this.state.dictionary.map(words => 
      <ScrollView> 
      <Text>{words.senses[0].english_definitions} {words.japanese[0].reading}</Text> 
      </ScrollView> 

     ); 
    } 
    } 

Моя делают функцию здесь:

render(){ 
    return(
    <View> 
    <Header/> 
     <Fumi    
     label={'Add Englishword....'} 
     iconClass={FontAwesomeIcon} 
     iconName={'pencil'} 
     iconColor={'#f95a25'} 
     onSubmitEditing={(wordLookUp) => { 

      this.sendData();  
     dismissKeyboard(); 
     }} 
     onChangeText={(wordLookUp) =>{ 
      this.setState({wordLookUp}); 
      console.log(wordLookUp); 
      this.sendData(); 
      this.renderList(); 
     }} 

     /> 
    {this.renderList()} 
    </View> 
    ) 

    } 
} 

Вот словарь, который вдохновил мой дизайн. http://www.nihongodict.com/w/15758/ichiranhyou/

Заранее спасибо.

+1

Супер полезный сайт! (Для тех, кто изучает японский язык), я думаю, вам нужно настроить буферную систему, чтобы ждать, пока пользователь больше не набирает текст. Например, подождите 300 мс, а затем возьмите значения и сделайте выборку. Если пользователь набирает букву, вы будете ставить в очередь запрос на выборку, но если пользователь снова наберет, вы отмените предыдущую очередь и создадите новую очередь еще на 300 мс. – Crysfel

+0

. Есть ли сайт, на который вы можете ссылаться. Я очень новичок в этом языке. Таким образом, любые ресурсы будут очень оценены. – o6t9o

ответ

1

Что я предлагаю подождать, пока пользователь не заполнит слово или буквы, которые хотят найти. Обычный подход заключается в том, чтобы, например, поставить в очередь функцию на 300 мс, а затем, если эта функция будет вызвана снова в течение 300 мс, выполнение снова затянется еще на 300 мс. Таким образом, если пользователь набирает очень быстро, вы не будете запрашивать сервер для каждого нажатия клавиши, но для окончательного результата.

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

function createBuffered(callback, buffer) { 
    var timerId; 

    return function(...params) { 
    if (timerId) { 
     clearTimeout(timerId); 
    } 

    timerId = setTimeout(function(){ 
     callback.apply(this, params); 
    }, buffer); 
    }; 
} 

Сначала вы должны создать функцию буферной функцию, то просто назвала его на каждом нажатии клавиши, она будет автоматически задерживать выполнение. Вот пример того, как его использовать.

class Testing extends Component { 
    state = { 
    query: '', 
    fetch: '', 
    }; 

    componentWillMount() { 
     // This function will be buffered for 300ms 
    this.fetchData = createBuffered((query) => { 
     // You should make your fetch request here. 
     this.setState({ 
     fetch: query, 
     }); 
    }, 300); 
    } 

    load(query) { 
    // This will be called constantly but nothing will happen until 
    // 300ms without activity on the input field 
    this.fetchData(query); 
    } 

    setQuery = (event) => { 
    // Just updating the state to save the input 
    const query = event.target.value; 
    this.setState({ 
     query, 
    }); 
    // Set the queue 
    this.load(query); 
    } 

    render() { 
    const { fetch, query } = this.state; 

    return (
     <View> 
     <Text>After 300ms, search for: {fetch}</Text> 
     <TextInput value={query} onChange={this.setQuery} /> 
     </View> 
    ); 
    } 
} 

Удачи!

Edit: Вот пример работает в reactjs только JSX это немного по-другому: https://jsfiddle.net/crysfel/fo7q6wzd/

+0

Большое вам спасибо за то, что нашли время, чтобы помочь мне. Я очень ценю это. Я попробую это и дам вам знать, как это работает для меня. – o6t9o