소스 검색

fix potential infinite pending of fetch promises

Gerald 9 년 전
부모
커밋
b903f1ac01
4개의 변경된 파일31개의 추가작업 그리고 33개의 파일을 삭제
  1. 1 0
      .gitignore
  2. 12 4
      src/background/db.js
  3. 8 10
      src/background/utils/script.js
  4. 10 19
      src/options/views/confirm.js

+ 1 - 0
.gitignore

@@ -1,4 +1,5 @@
 dist/
 node_modules/
 *.nex
+*.crx
 *.log

+ 12 - 4
src/background/db.js

@@ -339,12 +339,20 @@ define('vmdb', function (require, _exports, module) {
     var requests = {};
     return function (url) {
       var _this = this;
-      return requests[url]
-        || (requests[url] = scriptUtils.fetch(url).then(function (res) {
+      var promise = requests[url];
+      if (!promise) {
+        promise = requests[url] = scriptUtils.fetch(url)
+        .then(function (res) {
           return _this.saveRequire(url, res.responseText);
-        }).then(function () {
+        })
+        .catch(function () {
+          console.error('Error fetching required script: ' + url);
+        })
+        .then(function () {
           delete requests[url];
-        }));
+        });
+      }
+      return promise;
     };
   }();
 

+ 8 - 10
src/background/utils/script.js

@@ -4,17 +4,15 @@ define('utils/script', function (_require, _exports, module) {
       return url && !(/^(file|data):/.test(url));
     },
     fetch: function (url, type, headers) {
-      var xhr = new XMLHttpRequest;
-      xhr.open('GET', url, true);
-      if (type) xhr.responseType = type;
-      if (headers) for (var k in headers)
-        xhr.setRequestHeader(k, headers[k]);
       return new Promise(function (resolve, reject) {
-        xhr.onload = function () {
-          resolve(this);
-        };
-        xhr.onerror = function () {
-          reject(this);
+        var xhr = new XMLHttpRequest;
+        xhr.open('GET', url, true);
+        if (type) xhr.responseType = type;
+        if (headers) for (var k in headers) {
+          xhr.setRequestHeader(k, headers[k]);
+        }
+        xhr.onloadend = function () {
+          (xhr.status > 300 ? reject : resolve)(xhr);
         };
         xhr.send();
       });

+ 10 - 19
src/options/views/confirm.js

@@ -122,24 +122,22 @@ define('views/Confirm', function (require, _exports, module) {
       this.$('#msg').html(msg);
     },
     getFile: function (url, isBlob) {
-      var xhr = new XMLHttpRequest;
-      xhr.open('GET', url, true);
-      if (isBlob) xhr.responseType = 'blob';
       return new Promise(function (resolve, reject) {
-        xhr.onload = function () {
+        var xhr = new XMLHttpRequest;
+        xhr.open('GET', url, true);
+        if (isBlob) xhr.responseType = 'blob';
+        xhr.onloadend = function () {
+          if (xhr.status > 300) return reject(url);
           if (isBlob) {
             var reader = new FileReader;
             reader.onload = function () {
               resolve(window.btoa(this.result));
             };
-            reader.readAsBinaryString(this.response);
+            reader.readAsBinaryString(xhr.response);
           } else {
             resolve(xhr.responseText);
           }
         };
-        xhr.onerror = function () {
-          reject(url);
-        };
         xhr.send();
       });
     },
@@ -153,17 +151,10 @@ define('views/Confirm', function (require, _exports, module) {
         return text || Promise.reject();
       })
       .catch(function () {
-        return new Promise(function (resolve, reject) {
-          var xhr = new XMLHttpRequest;
-          xhr.open('GET', url, true);
-          xhr.onload = function () {
-            resolve(this.responseText);
-          };
-          xhr.onerror = function () {
-            _this.showMessage(_.i18n('msgErrorLoadingData'));
-            reject(this);
-          };
-          xhr.send();
+        return _this.getFile(url)
+        .catch(function (url) {
+          _this.showMessage(_.i18n('msgErrorLoadingData'));
+          throw url;
         });
       });
     },