request.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import fetch from 'dva/fetch';
  2. function checkStatus(response) {
  3. if(!response) {
  4. throw new Error('无法访问服务器');
  5. }
  6. if (response.status >= 200 && response.status < 300) {
  7. return response;
  8. }
  9. if (response.status === 400) {
  10. return response;
  11. }
  12. if (response.status === 404) {
  13. throw new Error('请求未找到');
  14. }
  15. if (response.status === 405) {
  16. throw new Error('无法访问服务器');
  17. }
  18. }
  19. /**
  20. * Requests a URL, returning a promise.
  21. *
  22. * @param {string} url The URL we want to request
  23. * @param {object} [options] The options we want to pass to "fetch"
  24. * @return {object} An object containing either "data" or "err"
  25. */
  26. class TimeoutError extends Error {
  27. constructor(message) {
  28. super(message);
  29. this.name = 'TimeoutError';
  30. }
  31. }
  32. /**
  33. * 提供参数校验和wrapper功能
  34. *
  35. * @param {*} url
  36. * @param {*} [options={ method: 'GET' }]
  37. * @returns {Promise} the request result
  38. */
  39. export default function request(url, options, timeout) {
  40. let retryCount = 0;
  41. class Request {
  42. constructor(url, {
  43. retry,
  44. ...options
  45. }) {
  46. this.url = url;
  47. this.retry = retry || 0;
  48. this.timeout = timeout || 8 * 1000;
  49. this.options = options;
  50. }
  51. then(fn) {
  52. let done = false;
  53. setTimeout(() => {
  54. // 无论是请求重试还是最终超时错误,此次请求得到的结果作废
  55. if (retryCount < this.retry && !done) {
  56. done = true;
  57. retryCount++;
  58. this.then(fn);
  59. } else {
  60. let error = new TimeoutError(`请求超时`);
  61. this.catchError(error);
  62. }
  63. }, this.timeout);
  64. fetch(this.url, this.options)
  65. .then(checkStatus)
  66. .then(data => {
  67. // 未进入重试或者超时错误,返回结果
  68. if (!done) {
  69. fn(
  70. data
  71. );
  72. done = true;
  73. }
  74. })
  75. .catch(err => {
  76. this.catchError(err);
  77. });
  78. return this;
  79. }
  80. catch (fn) {
  81. this.catchError = fn;
  82. }
  83. }
  84. return new Promise((resolve, reject) =>
  85. new Request(url, options).then(res => resolve(res)).catch(err => reject(err))
  86. );
  87. }