在每次api调用之前检查Server是否可以访问? [与API集成]

时间:2017-08-25 11:48:33

标签: api reactjs react-native react-redux

我有一个api模块类。看起来像这样

// General api to acces data from web
import ApiConstants from './ApiConstants';
export default function api(path,params,method){

    let options;
        options = Object.assign({headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }},{ method: method }, params ? { body: JSON.stringify(params) } : null );


    return fetch(ApiConstants.BASE_URL+path, options)
        .then(resp => resp.json())
        .then( json => json)
        .catch((error) => error);
    });
} 

我知道我们可以使用以下代码片段来检查我的后端服务器是否可以访问。

 const isAvailable = () => {
    const timeout = new Promise((resolve, reject) => {
        setTimeout(reject, 300, 'Request timed out');
    });

    const request = fetch('https://httpbin.org/delay/5');

    return Promise
        .race([timeout, request])
        .then(response => alert('It worked :)'))
        .catch(error => alert('It timed out :('));
}

isAvailable();
  

但是我怎么能以有效的方式结合这两个电话呢?我想在每次通话前检查服务器是否可以访问?

PS :即使网络可用,我的API服务器也只能使用 vpn 。因此,只有在检查服务器可达性后才能进行api调用。

  

如果服务器无法访问(Timeout not working)

,则React Native中的提取不会超时

编辑:正如@jevakallio在他的回答中提到的那样..添加服务器代码只会使代码更复杂。即使在本机反应中超时要高得多,最好的方法是使用下面提到的逻辑(@jevakallio)而不是使用超时。

2 个答案:

答案 0 :(得分:1)

您真的需要检查您的服务器是否可用?

相反,您可以尝试每次都触发实际请求,如果请求失败,请检查错误代码以扣除问题是由于服务器可用性还是其他一些错误。

类似的东西:

const NO_RESPONSE_CODE = 0;

return fetch(ApiConstants.BASE_URL+path, options)
    .then(resp => {
      if (resp.ok) {
        return resp.json();
      } else {

        if (resp.status === NO_RESPONSE_CODE) {
          // server unavailable
          return Promise.reject(new Error('Server unavailable'));
        } else {
          // handle other API errors here, implementation
          // depends on your response format
        }
      }
    })
    .then( json => json)
    .catch((error) => error);

这种机制更可取的原因是:

  1. 避免不必要的网络电话
  2. 通过取消预先检查来减少获得成功响应所需的时间
  3. 结果更可靠。即使您通过进行预检查请求来检查服务器是否可用,但在您提出实际的后续请求时,无法保证服务器仍然可用。移动网络可能令人惊讶地变幻无常,您的设备无线电可能会在请求之间丢失网络。

答案 1 :(得分:0)

也许这可以帮助

const isAvailable = () => {
    const timeout = new Promise((resolve, reject) => {
        setTimeout(reject, 300, 'Request timed out');
    });

    const request = fetch('https://httpbin.org/delay/5');

    return Promise
        .race([timeout, request])
        .then(response => alert('It worked :)'))
        .catch(error => alert('It timed out :('));
}

/ General api to acces data from web
import ApiConstants from './ApiConstants';
export default function api(path,params,method, sssid){

    let options;
        options = Object.assign({headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        }},{ method: method }, params ? { body: JSON.stringify(params) } : null );


    return isAvailable().then(() => fetch(ApiConstants.BASE_URL+path, options))
        .then(resp => resp.json())
        .then( json => json)
        .catch((error) => error);
    });
} 

在调用fetch之前始终调用isAvailable。一旦isAvailable结算,你就可以调用fetch api并在那时返回它的诺言。