Browse Source

fetch添加请求超时设置(默认30s)

zhuth 7 years ago
parent
commit
0d90e20b8b
1 changed files with 68 additions and 5 deletions
  1. 68 5
      src/utils/request.js

+ 68 - 5
src/utils/request.js

@@ -21,10 +21,73 @@ function checkStatus(response) {
  * @param  {object} [options] The options we want to pass to "fetch"
  * @return {object}           An object containing either "data" or "err"
  */
+
+class TimeoutError extends Error {
+  constructor(message) {
+    super(message);
+    this.name = 'TimeoutError';
+  }
+}
+
+/**
+ * 提供参数校验和wrapper功能
+ *
+ * @param {*} url
+ * @param {*} [options={ method: 'GET' }]
+ * @returns {Promise} the request result
+ */
 export default function request(url, options) {
-  return fetch(url, options)
-    .then(checkStatus)
-    .then(parseJSON)
-    .then(data => ({ data }))
-    .catch(err => ({ err }));
+  let retryCount = 0;
+
+  class Request {
+    constructor(url, {
+      retry,
+      timeout,
+      ...options
+    }) {
+      this.url = url;
+      this.retry = retry || 0;
+      this.timeout = timeout || 30000;
+      this.options = options;
+    }
+
+    then(fn) {
+      let done = false;
+      setTimeout(() => {
+        // 无论是请求重试还是最终超时错误,此次请求得到的结果作废
+        if (retryCount < this.retry && !done) {
+          done = true;
+          retryCount++;
+          this.then(fn);
+        } else {
+          let error = new TimeoutError(`timeout of ${this.timeout}ms execeeded`);
+          this.catchError(error);
+        }
+      }, this.timeout);
+
+      fetch(this.url, this.options)
+        .then(checkStatus)
+        .then(parseJSON)
+        .then(data => {
+          // 未进入重试或者超时错误,返回结果
+          if (!done) {
+            fn({data});
+            done = true;
+          }
+        })
+        .catch(err => {
+          this.catchError(err);
+        });
+
+      return this;
+    }
+
+    catch (fn) {
+      this.catchError = fn;
+    }
+  }
+
+  return new Promise((resolve, reject) =>
+    new Request(url, options).then(res => resolve(res)).catch(err => reject(err))
+  );
 }