• ES6 Promise 接口


    构造函数

    new Promise(function(resolve, reject){});
    

    构造函数接受一个函数(executor)作为参数,该函数在返回 Promise 实例之前被调用。函数的两个参数分别是 resolve 和 reject 函数。

    如果 executor 函数执行中抛出异常,则 Promise 视为 rejected。

    executor 函数返回值没有意义。

    类方法

    Promise.all(iterable)

    类似于 jQuery.when() 方法,只有 iterable 中所有的 Promise 都被 resolve,它返回一个新的被 resolve 的 Promise,resolved 值为 iterable 中所有 resolved 值组成的数组;或者 iterable 中只要有一个 Promise 被 reject,则立刻返回一个新的被 reject 的 Promise,rejected 值同时传递给新的 Promise。

    Promise.race(iterable)

    一旦 iterable 中任何一个 Promise 被 resolve 或 reject,则立即返回一个新的被 resolve 或 reject 的 Promise。

    Promise.reject(reason)

    返回一个 rejected Promise。

    Promise.resolve(value)

    返回一个新的 Promise。如果 value 是一个 thenable 对象(Promise),新 Promise 状态与 thenable 一致;否则新 Promise 状态为 resolved,Promise 结果为 value。

    实例方法

    Promise.prototype.catch(onRejected)

    返回一个新的 Promise。Promise 将 rejected 值视为一个 error,通过 catch 方法可以捕捉 rejected 值,并将该值传递给 onRejected 函数。onRejected 函数返回值将作为新 Promise 的 resolve 参数,也就是说,如果 onRejected 返回值是一个 Promise,则新 Promise 与该 Promise 状态一致;否则新 Promise 状态为 resolved,结果值为 onRejected 返回值。

    如果一个 rejected Promise 没有调用过 catch 方法,在谷歌浏览器控制台会输出异常提示 Uncaught (in promise) 1

    Promise.prototype.then(onFulfilled, onRejected)

    返回一个新 Promise。如果 onFulfilled 和 onRejected 是函数,则使用它们的返回值作为新 Promise 的 resolve 参数。否则新 Promise 与旧 Promise 状态保持一致。

    then 与 catch

    虽然 then 方法可以分别处理 resolution 和 rejection 两种情景,但 ES6 Promise 将 rejection 更多地视作异步异常情景,因此提供 catch 方法处理 rejection 情景。

    所以好的实践是使用 then 方法处理 resolution,catch 方法处理 rejection。

    // 不推荐
    asyncRun().then(function(value) {}, function(error) {});
    
    // 推荐
    asyncRun().then(function(value){}).catch(function(rejected) {});
    

    尤其当需要链接多个 Promise 时,使用 then + catch 模式会让代码更加清晰。

    // 不推荐
    asyncRun()
        .then(function(value) {}, function(error) {})
        .then(function(value) {}, function(error) {})
        .then(function(value) {}, function(error) {});
    
    // 推荐
    asyncRun()
        .then(function(value){})        
        .then(function(value){})
        .then(function(value){})
        .catch(function(rejected) {});
    

    Deferred 对象

    ES6 取消了 Deferred 对象,鼓励直接使用 Promise,而且主张 Promise 应该由它的创建者来 resolve 或 reject。

    但某些场景下,Deferred 对象仍然是一种更好的选择,尤其是 Promise 创建者与求值者分属不同对象时。

    基于 ES6 Promise 实现的 Deferred 对象

    简洁版:

    function Deferred() {
        var self = this;
        var promise = this.promise = new Promise(function(resolve, reject) {
            self.resolve = resolve;
            self.reject = reject;
        });
        this.then = this.promise.then.bind(promise);
        this.catch = this.promise.catch.bind(promise);
        this.catch(function() {});
    }
    

    完整版:

    /*
     * @Author: laixi
     * @Date:   2016-11-18 11:40:06
     * @Last Modified by:   laixi
     * @Last Modified time: 2016-11-18 12:36:26
     */
    var Deferred = function(beforeStart) {
      if (!(this instanceof Deferred)) {
        return new Deferred(beforeStart);
      }
    
      var _resolve;   // resolve function
      var _reject;  // reject function
      var _result;  // resolved value or rejected reason
      var _state = 'pending';   // promise status
      var doneCallbacks = [];
      var failCallbacks = [];
      var alwaysCallbacks = [];
    
      // create promise object
      var promise = new Promise(function(resolve, reject) {
        _resolve = resolve;
        _reject = reject;
      });
    
      // eliminate annoying error prompt at Chrome console
      promise.catch(function() {});
      
      // respectively call callbacks in done callback queue or fail callback queue
      promise.then(function(value) {
        _result = value;
        while (doneCallbacks.length > 0) {
          var callback = doneCallbacks.splice(0, 1)[0];
          callback.call(promise, value);
        }
      }, function(reason) {
        _result = reason;
        while (failCallbacks.length > 0) {
          var callback = failCallbacks.splice(0, 1)[0];
          callback.call(promise, reason);
        }
      });
    
      // extend promise by adding done, fail, always.
      // ----------------------------------------------
    
      promise.done = function(callback) {
        if (typeof callback === 'function') {
          if (_state === 'resolved') {
            callback.call(promise, _result);
          } else {
            doneCallbacks.push(callback);
          }
        }
        return promise;
      };
    
      promise.fail = function(callback) {
        if (typeof callback === 'function') {
          if (_state === 'rejected') {
            callback.call(promise, _result);
          } else {
            failCallbacks.push(callback);
          }
        }
        return promise;
      };
    
      promise.always = function(callback) {
        if (typeof callback === 'function') {
          if (_state === 'pending') {
            alwaysCallbacks.push(callback);
          } else {
            callback.call(promise, _result);
          }
        }
        return promise;
      };
    
      this.promise = function() {
        return promise;
      };
    
      this.state = function() {
        return _state;
      };
    
      this.resolve = function(value) {
        _state = 'resolved';
        _resolve.call(promise, value);
      };
    
      this.reject = function(reason) {
        _state = 'rejected';
        _reject.call(promise, reason);
      };
    
      this.catch = promise.catch.bind(promise);
      this.then = promise.then.bind(promise);
      this.done = promise.done.bind(promise);
      this.fail = promise.fail.bind(promise);
      this.always = promise.always.bind(promise);
    
      if (typeof beforeStart === 'function') {
        beforeStart.call(this, this);
      }
    };
    
  • 相关阅读:
    js的单元测试
    如何嵌入HTML 页面
    使用JQuery时间比较
    @page指令ValidateRequest的作用
    时间的正则表达式(比较简单)
    [置顶] Android代码 监控手机电池的状态
    [置顶] Android代码传感器光传感
    [置顶] Android问题ViewPager实现左右两个屏幕的切换
    [置顶] Android代码传感器测试手机支持那几种传感
    [置顶] Android代码检测手机耳机插拔
  • 原文地址:https://www.cnblogs.com/ifantastic/p/6077707.html
Copyright © 2020-2023  润新知