Promise

Promise定义

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.Promises/A+

Promise完成

状况机

Promise现实是一个状况机,从背面须要用到的状况最先完成Promise.

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
    //存储三种状况:PENDING, FULFILLED, REJECTED.初始状况是PENDING
    var state = PENDING;
    //存储效果或许毛病,一旦FULFILLED 或许 REJECTED
    var value = null;
    //存储sucess和failure处置惩罚函数,绑定在.then和.done
    var handlers = [];
}

下一步,增加两种过渡状况fulfilling和rejecting:

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise() {
  // store state which can be PENDING, FULFILLED or REJECTED
  var state = PENDING;

  // store value once FULFILLED or REJECTED
  var value = null;

  // store sucess & failure handlers
  var handlers = [];

  function fulfill(result) {
    state = FULFILLED;
    value = result;
  }

  function reject(error) {
    state = REJECTED;
    value = error;
  }
}

上面是两种低级过渡,下面是更高等的过渡,叫做resolve:

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

function Promise() {
  // store state which can be PENDING, FULFILLED or REJECTED
  var state = PENDING;

  // store value once FULFILLED or REJECTED
  var value = null;

  // store sucess & failure handlers
  var handlers = [];

  function fulfill(result) {
    state = FULFILLED;
    value = result;
  }

  function reject(error) {
    state = REJECTED;
    value = error;
  }

  function resolve(result) {
    try {
      var then = getThen(result);
      if (then) {
        doResolve(then.bind(result), resolve, reject)
        return
      }
      fulfill(result);
    } catch (e) {
      reject(e);
    }
  }
}

/**
 * Check if a value is a Promise and, if it is,
 * return the `then` method of that promise.
 *
 * @param {Promise|Any} value
 * @return {Function|Null}
 */
function getThen(value) {
  var t = typeof value;
  if (value && (t === 'object' || t === 'function')) {
    var then = value.then;
    if (typeof then === 'function') {
      return then;
    }
  }
  return null;
}

/**
 * Take a potentially misbehaving resolver function and make sure
 * onFulfilled and onRejected are only called once.
 *
 * Makes no guarantees about asynchrony.
 *
 * @param {Function} fn A resolver function that may not be trusted
 * @param {Function} onFulfilled
 * @param {Function} onRejected
 */
function doResolve(fn, onFulfilled, onRejected) {
  var done = false;
  try {
    fn(function (value) {
      if (done) return
      done = true
      onFulfilled(value)
    }, function (reason) {
      if (done) return
      done = true
      onRejected(reason)
    })
  } catch (ex) {
    if (done) return
    done = true
    onRejected(ex)
  }
}

以上代码的简朴完成看参考:https://github.com/then/promise/blob/master/src/core.js

Promise状况

Promise对象有以下几种状况:

  • pending: 初始状况, 非 fulfilled 或 rejected.

  • fulfilled: 胜利的操纵.(假如promise.then(f),马上挪用f)

  • rejected: 失利的操纵.(假如promise.then(undefined, r),马上挪用r)

假如一个promise对象处在fulfilled或rejected状况而不是pending状况,那末它也能够被称为settled状况。你能够也会听到一个术语resolved,它示意promise对象处于settled状况,或许promise对象被锁定在了挪用链中。settled不是一种状况,而是一种语法上的方便。

Promise要领

Promise.resolve(value/promise/thenable)

Promise.resolve(value)要领返回一个以给定值resolve掉的Promise对象。但假如这个值是thenable的(就是说带有then要领),返回的promise会“跟随”这个thenable的对象,吸收它的终究状况(指resolved/rejected/pendding/settled);不然这个被返回的promise对象会以这个值被fulfilled。

//Example
var p = Promise.resolve([1,2,3]);
p.then(function(v) {
  console.log(v[0]); // 1
});
//Polyfill
Promise.resolve = function (value) {
  return new Promise(function (resolve) {
    resolve(value);
  });
};

Promise.reject(reason)

Promise.reject(reason)要领返回一个用reason谢绝的Promise.

//Example
Promise.reject(new Error("fail")).then(function(error) {
  // 未被挪用
}, function(error) {
  console.log(error); // 客栈跟踪
});
//Polyfill
Promise.reject = function (value) {
  return new Promise(function (resolve, reject) {
    reject(value);
  });
};

Promise.race(iterable)

Promise.race(iterable)要领返回一个promise,这个promise在iterable中的恣意一个promise被处理或谢绝后,马上以雷同的处理值被处理或以雷同的谢绝原因被谢绝。

//Example
var p1 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 500, "一"); 
});
var p2 = new Promise(function(resolve, reject) { 
    setTimeout(resolve, 100, "二"); 
});

Promise.race([p1, p2]).then(function(value) {
  console.log(value); // "二"
  // 两个都处理,但p2更快
});
//Polyfill
Promise.race = function (values) {
  // TODO: this polyfill only supports array-likes
  //       it should support all iterables
  return new Promise(function (resolve, reject) {
    values.forEach(function(value){
      Promise.resolve(value).then(resolve, reject);
    });
  });
};

Promise.all(iterable)

Promise.all(iterable) 要领返回一个promise,该promise会在iterable参数内的一切promise都被处理后被处理。

//Example
var p1 = new Promise(function(resolve, reject) { 
  setTimeout(resolve, 1000, "one"); 
}); 
var p2 = new Promise(function(resolve, reject) { 
  setTimeout(resolve, 2000, "two"); 
});
var p3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 3000, "three");
});
var p4 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 4000, "four");
});
var p5 = new Promise(function(resolve, reject) {
  reject("reject");
});

Promise.all([p1, p2, p3, p4, p5]).then(function(value) { 
  console.log(value);
}, function(reason) {
  console.log(reason)   //"reject"
});
//Polyfill
Promise.all = function (arr) {
  // TODO: this polyfill only supports array-likes
  //       it should support all iterables
  var args = Array.prototype.slice.call(arr);

  return new Promise(function (resolve, reject) {
    if (args.length === 0) return resolve([]);
    var remaining = args.length;
    function res(i, val) {
      if (val && (typeof val === 'object' || typeof val === 'function')) {
        var then = val.then;
        if (typeof then === 'function') {
          var p = new Promise(then.bind(val));
          p.then(function (val) {
            res(i, val);
          }, reject);
          return;
        }
      }
      args[i] = val;
      if (--remaining === 0) {
        resolve(args);
      }
    }
    for (var i = 0; i < args.length; i++) {
      res(i, args[i]);
    }
  });
};

Promise.prototype.then(onFulfilled, onRejected)

Promise实例具有then要领,也就是说,then要领是定义在原型对象Promise.prototype上的。它的作用是为Promise实例增加状况转变时的回调函数。

//Example
var p1 = new Promise(function(resolve, reject) {
  resolve("Success!");
  // or
  // reject ("Error!");
});

p1.then(function(value) {
  console.log(value); // Success!
}, function(reason) {
  console.log(reason); // Error!
});

Promise.prototype.catch(onRejected)

等同于挪用Promise.prototype.then(undefined, onRejected)

//Example
var p1 = new Promise(function(resolve, reject) {
  resolve("Success");
});

p1.then(function(value) {
  console.log(value); // "Success!"
  throw "oh, no!";
}).catch(function(e) {
  console.log(e); // "oh, no!"
});
//Polyfill
Promise.prototype['catch'] = function (onRejected) {
  return this.then(null, onRejected);
};

参考资本

MDN Promise
Promise官方文档
Promise对象
then/promise

    原文作者:sundway
    原文地址: https://segmentfault.com/a/1190000004152854
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞