2016-08-17 33 views
1

因此,我們遇到了一個問題,即我們向SQS發送請求,然後在接收消息中不返回任何數據。從AWS SQS提取數據並等待渲染ReactJs

爲了嘗試解決這個問題,我們在while循環中投擲了很長一段時間;然而,這確實不起作用,因爲我們無法在民意調查之間入睡,而且看起來好像它們都是異步發生的。

我這樣說,因爲如果該值確實返回(發生約50%的時間),它將重新呈現下一個屏幕,儘可能多的時間留下帽子並且輪詢不會被設置爲false。有人可以幫助我們!

render() { 
    return (
     <Navigator 
      renderScene={this.renderScene.bind(this)} 
      navigator={this.props.navigator} 
      navigationBar={ 
      <Navigator.NavigationBar style={{backgroundColor: 'transparent'}} 
       routeMapper={NavigationBarRouteMapper} /> 
      } /> 
    ); 
    } 

renderScene() { 
    return (
     <View style={styles.container}> 
     <StatusBar barStyle="light-content" hidden={true}/> 
     <View style={styles.topContainer}> 
      <View style={styles.bannerContainer}> 
      <View style={{flexDirection: 'column', flex: 1, justifyContent: 'center', alignItems: 'center'}}> 
       <Image style={styles.mark} source={require('./yb.png')} /> 
      </View> 
      </View> 
      <View style={styles.credentialContainer}> 
      <View style={styles.inputContainer}> 
       <Icon style={styles.inputPassword} name="person" size={28} color="#FFCD00" /> 
        <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}> 
        <TextInput 
         style={styles.input} 
         placeholder="Username" 
         autoCorrect={false} 
         placeholderTextColor="#e0e0e0" 
         onChangeText={(text) => this.setState({username: text})} 
         value={this.state.username}> 
        </TextInput> 
        </View> 
       </View> 

       <View style={styles.inputContainer}> 
        <Icon style={styles.inputPassword} name="lock" size={28} color="#FFCD00" /> 
        <View style={{flexDirection: 'row', flex: 1, marginLeft: 2, marginRight: 2, borderBottomColor: '#e0e0e0', borderBottomWidth: 2}}> 
        <TextInput 
         style={styles.input} 
         placeholder="Password" 
         autoCorrect={false} 
         secureTextEntry={true} 
         placeholderTextColor="#e0e0e0" 
         onChangeText={(text) => this.setState({password: text})} 
         value={this.state.password}> 
         </TextInput> 
        </View> 
       </View> 
       <TouchableOpacity style={styles.forgotContainer}> 
        <Text style={{color: '#e0e0e0'}}>Forgot Password</Text> 
       </TouchableOpacity> 
      </View> 
     </View> 

     <TouchableHighlight 
      underlayColor="#D6AB00" 
      onPress={this.login} 
      style={styles.signInButtonContainer}> 
      <Text style={styles.signInText}>Sign In</Text> 
     </TouchableHighlight>  
     </View> 
    ); 
    } 

    login() { 
    var polling = true; 
    if(this.state.username.length == 0){ 
     Alert.alert("Error","No email entered"); 
    } 
    else if(this.state.password.length == 0){ 
     Alert.alert("Error","No password entered"); 
    } 
    else 
    {  
    info.username = this.state.username; 
    info.password = this.state.password; 

    AWS.sendMessage('****',JSON.stringify(info), (error,result) =>{ 
     if(error != null) console.log("Error Occured Attempting to Send A Message") 
     else { 
     var cap=0; 
     while(cap <= 30 && polling){ 
     cap = cap+1; 

      AWS.receiveMessages('****'+info.username, (error, result) =>{ 
      if(error != null) console.log("Error"); 
      else{ 
       if(result){ 
       try{ 
        polling = false; 
        if(result[0] == "[]") 
        { 
         console.log(result[0]); 
         console.log(typeof result[0]); 
         Alert.alert("Error","Username/Password Incorrect"); 
        } 
        else 
        { 
         console.log(result[0]); 
         console.log(typeof result[0]); 
         var temp = JSON.parse(result[0]); 
         this.props.navigator.replace({ 
         id: 'MapIOS', 
         data: { 
          username: info.username, 
          ofAge: temp[0].ofAge, 
          uid: temp[0].u_ID 
         }, 
         }); 
        } 
       } 
       catch(e){ 
        console.log(e); 
       } 
       } 
       AWS.deleteMessage('***'+info.username, result[1], (error) => { 
       if(error != null) console.log("Error"); 
       }); 
      } 
      }); 
     } 
     return 
     } 
    }); 
    } 
    } 
}; 

回答

1

問題是你在循環中調用AWS.ReceiveMessage

當您撥打AWS.ReceiveMessage時,該呼叫是異步的。意思是,它會立即返回。它不會等待您的回調被調用。所以你的循環可以在任何回調被調用之前用盡。

試圖從您的回調函數設置您的polling變量不是一種安全的方法來「保護」您的回調。

您需要重構您的功能,以便第二個AWS.ReceiveMessage不會發生,直到從第一個AWS.ReceiveMessage調用回調之後。

一般來說,不要循環。

+0

我同意你的建議,但是如何在沒有循環的情況下做到這一點?我想這或多或少是我缺乏知識。我期望它現在運行的方式是,如果收到消息,它會刪除它,它會RecieveMessage。如果不是,它會再次調用RecieveMessage。這顯然不會發生,所以我會怎麼做,沒有循環? – wdlax11

+0

看看這樣的東西:http:// stackoverflow。com/questions/18581483/how-to-do-repeated-requests-until-one-succeeds-without-blocking-in-node –

+0

所以或多或少的代替循環,我應該把代碼中的請求數據段變成函數和「遞歸」調用該函數,直到它返回數據? – wdlax11

1

約SQS一些重要的事實,你需要記住使用時:

  1. SQS不是「先入先出」。消息可能不會按照放入隊列的順序接收。因此,如果您添加消息「1」和「2」,則可能會將它們接收爲「2」,然後是「1」。
  2. 即使消息在隊列中,當您撥打ReceiveMessage時也可能不會收到消息。
  3. 您可能會多次收到相同的消息。例如,如果您向隊列中添加了消息「1」,稍後您可能會再次返回「1」,然後再返回「1」。所以你需要確保消息處理是冪等和重複安全的。

以上都是因爲SQS是分佈式和冗餘的。它保證你會得到你的消息,但它不能保證訂單或消息被接收的次數。

更新:

這是我原來的答案,但我不認爲這是一個與代碼的首要問題。我將它留在這裏,因爲我認爲它仍然是有價值的信息。

+0

感謝您的背景資料!但我同意你的其他答案更多是我們需要的。 – wdlax11