2017-02-09 76 views
3

我有一个工作的用户登录功能。但是,我想为提取合并超时错误。有没有办法设置一个计时器5秒左右,以避免在这样的时间后试图获取?否则,我会在一段时间之后发现网络错误,然后出现红色屏幕。做超时错误而取 - 阵营本地

_userLogin() { 
    var value = this.refs.form.getValue(); 
    if (value) { // if validation fails, value will be null 
    if (!this.validateEmail(value.email)) { 
     Alert.alert(
      "Enter a valid email", 
     ) 
    } else { 
     fetch("http://51.64.34.134:5000/api/login", {  
     method: "POST", 
     headers: { 
      'Accept': 'application/json', 
      'Content-Type': 'application/json' 
     }, 
     timeout: 5000, 
     body: JSON.stringify({ 
      username: value.email, 
      password: value.password, 
     }) 
     }) 
     .then((response) => response.json()) 
     .then((responseData) => { 
     if (responseData.status == "success") { 
     this._onValueChange(STORAGE_KEY, responseData.data.token) 
     Alert.alert(
      "Login Success!", 
     ) 
     this.props.navigator.push({ name: 'StartScreen'}) 
     } else if (responseData.status == "error") { 
     Alert.alert(
      "Login Error", 
      responseData.message 
     ) 
     } 
     }) 
     .done(); 
    } 
    }},  

回答

1

没有标准的方法来处理这个问题,如a timeout option isn't defined in the official spec yetThere is an abort defined,您可以将其与自己的超时和承诺一起使用。例如,如看到herehere。我已经复制了示例代码,但尚未自行测试。

// Rough implementation. Untested. 
function timeout(ms, promise) { 
    return new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     reject(new Error("timeout")) 
    }, ms) 
    promise.then(resolve, reject) 
    }) 
} 

timeout(1000, fetch('/hello')).then(function(response) { 
    // process response 
}).catch(function(error) { 
    // might be a timeout error 
}) 

另一种办法是修改fetch.js模块自己添加为看到here是中止调用超时。

+0

通过这样做此超时,它只能解决问题的表面,它不能放弃一定时间后请求。 – TomSawyer

+0

@TomSawyer尽管这并不是什么问题;该问题并没有要求在超时后处理中止。另外,我的答案确实包含了可能的解决方案的链接,以便在其他人希望朝着这个方向前进时中止。所以我不太确定你评论的重点是什么? –

+0

我指出谁关心超时机制是如何工作的。在HTTP请求,这意味着中止连接一个连接超时,其分配的内存必须释放,其过程中需要被终止不仅为UI更新返回false然后继续在后台运行。 – TomSawyer

0

我用2项承诺之间的竞争,写成一个包装器获取解决了这个问题。在我的情况下,我期望返回json的请求也添加了这个。也许有更好的解决方案,但这对我来说是正确的!

的包装返回只要没有代码中的错误,这将解决一个承诺。 您可以检查result.status中的'success'并从result.data中读取json数据。如果发生错误,您可以读取result.data中的确切错误,并将其显示或记录在某处。这样你总是知道出了什么问题!

var yourFetchWrapperFunction = function(method, url, headers, body, timeout=5000){  
var timeoutPromise = new Promise(function(resolve,reject){ 
         setTimeout(resolve, timeout, {status: 'error', code: 666, data: 'Verbinding met de cloud kon niet tot stand gebracht worden: Timeout.'}); 
         }); 
    return Promise.race([timeoutPromise, fetch(connectionType + '://' + url, {method: method, headers: headers, body: body})]).then((result) => { 
         var Status = result.status; 
         return result.json().then(function(data){ 
          if (Status === 200 || Status === 0) { 
          return {status: 'success', code: Status, data: data}; 
          } 
          else { 
          return {status: 'error', code: Status, data: 'Error (' + data.status_code + '): ' + data.message}; 
          } 
         },function (response) { 
          return {status: 'error', code: Status, data: 'json promise failed' + response}; 
         }).catch((error) => { 
          return {status: 'error', code: 666, data: 'no json response'}; 
         }); 
         }, function(error){ 
          return {status: 'error', code: 666, data: 'connection timed out'}; 
         }).catch((error) => { 
          return {status: 'error', code: 666, data: 'connection timed out'}; 
         }); 
} 
0

这是我做过什么去解决它: (该是“通用”的功能,我使用,使我的应用程序的所有调用)

我创建了一个超时功能,将被触发除非是前清零,然后我清除服务器响应

const doFetch = (url, callback, data) => { 

    //... creating config obj here (not relevant for this answer) 

    var wasServerTimeout = false; 

    var timeout = setTimeout(() => { 
    wasServerTimeout = true; 
    alert('Time Out') 
    } , 3000) 


     fetch(HOST + url, config) 
     .then((response) => { 

     timeout && clearTimeout(timeout); //If everything is ok, clear the timeout 

    if(!wasServerTimeout){ 
     return response.json() 
    } 
     }) 
     .then((response) => { 
       callback && callback(response.data || response); 
     }).catch((err) => { 

      timeout && clearTimeout(timeout); //If something goes wrong, clear the timeout 

    if(!wasServerTimeout){ 
      //Error logic here 
     } 

     }); 
    }