浏览代码

去除polifill

Luolei 6 年之前
父节点
当前提交
500500ea60
共有 5 个文件被更改,包括 403 次插入24 次删除
  1. 0 3
      package.json
  2. 0 19
      src/html/index.html
  3. 1 2
      src/js/promise.js
  4. 398 0
      src/js/rePromise.js
  5. 4 0
      webpack.config.js

+ 0 - 3
package.json

@@ -4,11 +4,8 @@
   "description": "",
   "main": "index.js",
   "dependencies": {
-    "@babel/polyfill": "^7.4.4",
-    "babel-polyfill": "^6.26.0",
     "es3ify-loader": "^0.2.0",
     "jquery": "^1.12.4",
-    "webpack": "^4.30.0",
     "webpack-cli": "^3.3.1"
   },
   "devDependencies": {

文件差异内容过多而无法显示
+ 0 - 19
src/html/index.html


+ 1 - 2
src/js/promise.js

@@ -1,7 +1,6 @@
-// require("babel-polyfill");
-require("@babel/polyfill");
 const qs = require('qs');
 const $ = require("jquery");
+var Promise = require('./rePromise');
 
 const config = {
   pushInner:'/api/icss/push/pushInner',

+ 398 - 0
src/js/rePromise.js

@@ -0,0 +1,398 @@
+/**
+     * Promise对象的内部状态
+     *
+     * @type {Object}
+     */
+    var Status = {
+      PENDING: 'pending',
+      FULLFILLED: 'resolved',
+      REJECTED: 'rejected'
+  };
+
+  function empty() {}
+
+  /**
+   * Promise构造函数
+   *
+   * @constructor
+   * @param {Function} resolver 此Promise对象管理的任务
+   */
+  function Promise(resolver) {
+      // ES6原生的Promise构造函数中,若不通过`new`调用Promise的构造函数,会抛出TypeError异常。此处与其一致
+      if (!(this instanceof Promise)) {
+          throw new TypeError('TypeError: undefined is not a promise');
+      }
+
+      // ES6原生的Promise构造函数中,若无作为函数的resolver参数,会抛出TypeError异常。此处与其一致
+      if (typeof resolver !== 'function') {
+          throw new TypeError('TypeError: Promise resolver undefined is not a function');
+      }
+
+      /**
+       * Promise对象内部的状态,初始为`pending`。状态只能由`pending`到`fullfilled`或`rejected`
+       *
+       * @type {string}
+       */
+      this._status = Status.PENDING;
+
+      /**
+       * Promise对象resolved/rejected后拥有的data/reason
+       *
+       *  - 此处保存此值是为了当一个Promise对象被resolved或rejected后,继续对其调用`then`添加任务,后续处理仍能获得当前Promise的值
+       *
+       * @type {Mixed}
+       */
+      this._value;
+
+      /**
+       * 当前Promise被resolved/rejected后,需处理的任务
+       *
+       *  - 由于同一个Promise对象可以调用多次`then`方法,以添加多个并行任务,所以此处是一个数组
+       *
+       * @type {Array.<Function>}
+       */
+      this._doneCallbacks = [];
+      this._failCallbacks = [];
+
+      var promise = this;
+      resolver(
+          function (data) {
+              resolve(promise, data);
+          },
+          function (reason) {
+              reject(promise, reason);
+          }
+      );
+  }
+
+  Promise.prototype = {
+
+      constructor: Promise,
+
+      /**
+       * Promise的`then`方法
+       *
+       * @param {Function|Mixed} onResolve 当前Promise对象被resolved后,需处理的任务
+       * @param {Function|Mixed} onReject 当前Promise对象被rejected后,需处理的任务
+       * @return {Promise} 返回一个新的Promise对象,用于链式操作
+       */
+      then: function (onResolve, onReject) {
+          var promise = new Promise(empty);
+
+          this._doneCallbacks.push(makeCallback(promise, onResolve, 'resolve'));
+          this._failCallbacks.push(makeCallback(promise, onReject, 'reject'));
+
+          // 如果在一个已经被fullfilled或rejected的promise上调用then,则需要直接执行通过then注册的回调函数
+          run(this);
+
+          return promise;
+      },
+
+      /**
+       * Promise的`done`方法
+       *
+       * @param {Function|Mixed} onResolve 当前Promise对象被resolved后,需处理的任务
+       * @return {Promise} 返回一个新的Promise对象,用于链式操作
+       */
+      done: function (onResolve) {
+          return this.then(onResolve, null);
+      },
+
+      /**
+       * Promise的`fail`方法
+       *
+       * @param {Function|Mixed} onReject 当前Promise对象被rejected后,需处理的任务
+       * @return {Promise} 返回一个新的Promise对象,用于链式操作
+       */
+      fail: function (onReject) {
+          return this.then(null, onReject);
+      },
+
+      /**
+       * Promise的`catch`方法
+       *
+       * @param {Function|Mixed} onFail 当前Promise对象被rejected后,需处理的任务
+       * @return {Promise} 返回一个新的Promise对象,用于链式操作
+       */
+      catch: function (onFail) {
+          return this.then(null, onFail);
+      }
+  };
+
+  /**
+   * 创建一个Promise对象,并用给定值resolve它
+   *
+   * @param {Mixed} value 用于resolve新创建的Promise对象的值
+   * @return {Promise} 返回一个新的Promise对象,用于链式操作
+   */
+  Promise.resolve = function (value) {
+      var promise = new Promise(empty);
+      resolve(promise, value);
+      return promise;
+  };
+
+  /**
+   * 创建一个Promise对象,并用给定值reject它
+   *
+   * @param {Mixed} reason 用于reject新创建的Promise对象的值
+   * @return {Promise} 返回一个新的Promise对象,用于链式操作
+   */
+  Promise.reject = function (reason) {
+      var promise = new Promise(empty);
+      reject(promise, reason);
+      return promise;
+  };
+
+  /**
+   * 返回一个promise,这个promise在iterable中的任意一个promise被解决或拒绝后,
+   * 立刻以相同的解决值被解决或以相同的拒绝原因被拒绝
+   *
+   * @param {Iterable.<Promise|Mixed>} iterable 一组Promise对象或其它值
+   * @return {Promise} 返回一个新的Promise对象,用于链式操作
+   */
+  Promise.race = function (iterable) {
+      if (!iterable || !iterable.hasOwnProperty('length')) {
+          throw new TypeError('TypeError: Parameter `iterable` must be a iterable object');
+      }
+
+      var promise = new Promise(empty);
+      for (var i = 0, len = iterable.length; i < len; i++) {
+          var iterate = iterable[i];
+          if (!(iterate instanceof Promise)) {
+              iterate = Promise.resolve(iterate);
+          }
+
+          iterate.then(resolveRaceCallback, rejectRaceCallback);
+      }
+
+      var settled = false;
+
+      function resolveRaceCallback(data) {
+          if (settled) {
+              return;
+          }
+
+          settled = true;
+          resolve(promise, data);
+      }
+
+      function rejectRaceCallback(reason) {
+          if (settled) {
+              return;
+          }
+
+          settled = true;
+          reject(promise, reason);
+      }
+  };
+
+  /**
+   * 返回一个promise,该promise会在iterable参数内的所有promise都被解决后被解决
+   *
+   * @param {Iterable.<Promise|Mixed>} iterable 一组Promise对象或其它值
+   * @return {Promise} 返回一个新的Promise对象,用于链式操作
+   */
+  Promise.all = function (iterable) {
+      if (!iterable || !iterable.hasOwnProperty('length')) {
+          throw new TypeError('TypeError: Parameter `iterable` must be a iterable object');
+      }
+
+      var promise = new Promise(empty);
+      var length = iterable.length;
+      for (var i = 0; i < length; i++) {
+          var iterate = iterable[i];
+          if (!(iterate instanceof Promise)) {
+              iterate = Promise.resolve(iterate);
+          }
+
+          iterate.then(makeAllCallback(iterate, i, 'resolve'), makeAllCallback(iterate, i, 'reject'));
+      }
+
+      var result = [];
+      var count = 0;
+
+      function makeAllCallback(iterate, index, action) {
+          return function (value) {
+              if (action === 'reject') {
+                  reject(promise, value);
+                  return;
+              }
+
+              result[index] = value;
+
+              if (++count === length) {
+                  resolve(promise, result);
+              }
+          }
+      }
+  };
+
+  /**
+   * 返回一个Deferred对象,包含一个新创建的Promise对象,以及`resolve`和`reject`方法
+   *
+   * @return {Deferred}
+   */
+  Promise.defer = function () {
+      var promise = new Promise(empty);
+
+      return {
+          promise: promise,
+          resolve: function (data) {
+              resolve(promise, data);
+          },
+          reject: function (reason) {
+              reject(promise, reason);
+          }
+      };
+  };
+
+  function run(promise) {
+      // `then`方法中也会调用,所以此处仍需做一次判断
+      if (promise._status === Status.PENDING) {
+          return;
+      }
+
+      var value = promise._value;
+      var callbacks = promise._status === Status.FULLFILLED
+          ? promise._doneCallbacks
+          : promise._failCallbacks;
+
+      // Promise需要异步操作
+      setTimeout(function () {
+          for (var i = 0, len = callbacks.length; i < len; i++) {
+              callbacks[i](value);
+          }
+      });
+
+      // 每个promise只能被执行一次。虽然`_doneCallbacks`和`_failCallbacks`用户不应该直接访问,
+      // 但还是可以访问到,保险起见,做清空处理。
+      promise._doneCallbacks = [];
+      promise._failCallbacks = [];
+  }
+
+  function resolve(promise, data) {
+      if (promise._status !== Status.PENDING) {
+          return;
+      }
+
+      promise._status = Status.FULLFILLED;
+      promise._value = data;
+
+      run(promise);
+  }
+
+  function reject(promise, reason) {
+      if (promise._status !== Status.PENDING) {
+          return;
+      }
+
+      promise._status = Status.REJECTED;
+      promise._value = reason;
+
+      run(promise);
+  }
+
+  function makeCallback(promise, callback, action) {
+      return function promiseCallback(value) {
+          // 如果传递了callback,则使用前一个promise传递过来的值作为参数调用callback,
+          // 并根据callback的调用结果来处理当前promise
+          if (typeof callback === 'function') {
+              var x;
+              try {
+                  x = callback(value);
+              }
+              catch (e) {
+                  // 如果调用callback时抛出异常,则直接用此异常对象reject当前promise
+                  reject(promise, e);
+              }
+
+              // 如果callback的返回值是当前promise,为避免造成死循环,需要抛出异常
+              // 根据Promise+规范,此处应抛出TypeError异常
+              if (x === promise) {
+                  var reason = new TypeError('TypeError: The return value could not be same with the promise');
+                  reject(promise, reason);
+              }
+              // 如果返回值是一个Promise对象,则当返回的Promise对象被resolve/reject后,再resolve/reject当前Promise
+              else if (x instanceof Promise) {
+                  x.then(
+                      function (data) {
+                          resolve(promise, data);
+                      },
+                      function (reason) {
+                          reject(promise, reason);
+                      }
+                  );
+              }
+              else {
+                  var then;
+                  (function resolveThenable(x) {
+                      // 如果返回的是一个Thenable对象(此处逻辑有点坑,参照Promise+的规范实现)
+                      if (x && (typeof x === 'object'|| typeof x === 'function')) {
+                          try {
+                              then = x.then;
+                          }
+                          catch (e) {
+                              reject(promise, e);
+                              return;
+                          }
+
+                          if (typeof then === 'function') {
+                              // 调用Thenable对象的`then`方法时,传递进去的`resolvePromise`和`rejectPromise`方法(及下面的两个匿名方法)
+                              // 可能会被重复调用。但Promise+规范规定这两个方法有且只能有其中的一个被调用一次,多次调用将被忽略。
+                              // 此处通过`invoked`来处理重复调用
+                              var invoked = false;
+                              try {
+                                  then.call(
+                                      x,
+                                      function (y) {
+                                          if (invoked) {
+                                              return;
+                                          }
+                                          invoked = true;
+
+                                          // 避免死循环
+                                          if (y === x) {
+                                              throw new TypeError('TypeError: The return value could not be same with the previous thenable object');
+                                          }
+
+                                          // y仍有可能是thenable对象,递归调用
+                                          resolveThenable(y);
+                                      },
+                                      function (e) {
+                                          if (invoked) {
+                                              return;
+                                          }
+                                          invoked = true;
+
+                                          reject(promise, e);
+                                      }
+                                  );
+                              }
+                              catch (e) {
+                                  // 如果`resolvePromise`和`rejectPromise`方法被调用后,再抛出异常,则忽略异常
+                                  // 否则用异常对象reject此Promise对象
+                                  if (!invoked) {
+                                      reject(promise, e);
+                                  }
+                              }
+                          }
+                          else {
+                              resolve(promise, x);
+                          }
+                      }
+                      else {
+                          resolve(promise, x);
+                      }
+                  }(x));
+              }
+          }
+          // 如果未传递callback,直接用前一个promise传递过来的值resolve/reject当前Promise对象
+          else {
+              action === 'resolve'
+                  ? resolve(promise, value)
+                  : reject(promise, value);
+          }
+      };
+  }
+
+  module.exports = Promise

+ 4 - 0
webpack.config.js

@@ -119,6 +119,10 @@ module.exports = {
             properties: false,
             warnings: false
           },
+          mangle: {
+            screw_ie8: false,
+            except: ['e']
+          },
           output: {
               beautify: true
           },