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);
};