文章目录
Promise标准解读
-
只有一个then方法,没有catch,race,all等方法,甚至没有构造函数 Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定,包括catch,race,all等常用方法,甚至也没有指定该如何构造出一个Promise对象,另外then也没有一般实现中(Q, $q等)所支持的第三个参数,一般称onProgress
-
then方法返回一个新的Promise
-
不同Promise的实现需要可以相互调用(interoperable)
-
Promise的初始状态为pending,它可以由此状态转换为fulfilled(本文为了一致把此状态叫做resolved)或者rejected,一旦状态确定,就不可以再次转换为其它状态,状态确定的过程称为settle
promise实现
try {
module.exports = Promise
} catch (e) { }
function Promise(exec) {
var self = this;
self.status = 'pending';
self.onResolvedCallback = [];
self.onRejectedCallback = [];
function resolve(value) {
if (value instanceof Promise) {
return value.then(resolve, reject);
}
setTimeout(function () {
if (self.status === 'pending') {
self.status = 'resolved';
self.data = value;
for (var i = 0; i < self.onResolvedCallback.length; i++) {
self.onResolvedCallback[i](value);
}
}
})
}
function reject(reason) {
setTimeout(function () {
if (self.status === 'pending') {
self.status = 'rejected';
self.data = reason;
for (var i = 0; i < self.onRejectedCallback.length; i++) {
self.onRejectedCallback[i](reason);
}
}
})
}
try {
exec(resolve, reject);
} catch (error) {
reject(err)
}
}
function resolvePromise(promise2, x, resolve, reject) {
var then
var thenCanceldOrThrow = false
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise!'))
}
if (x instanceof Promise) {
if (x.status === 'pending') {
x.then(function (v) {
resolvePromise(promise2, v, resolve, reject);
}, reject);
} else {
x.then(resolve, reject);
}
return
}
if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) {
try {
then = x.then
if (typeof then === 'function') {
then.call(x, function rs(val) {
if (thenCanceldOrThrow) return
thenCanceldOrThrow = true;
return resolvePromise(promise2, val, resolve, reject)
}, function rj(reason) {
if (thenCanceldOrThrow) return
thenCanceldOrThrow = true;
return reject(reason);
})
} else {
resolve(x)
}
} catch (err) {
if (thenCanceldOrThrow) return
thenCanceldOrThrow = true;
return reject(err);
}
} else {
resolve(x)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
var self = this;
var promise2;
onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value };
onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { throw reason };
if (self.status === 'resolved') {
return promise2 = new Promise(function (resolve, reject) {
setTimeout(function () {
try {
var x = onResolved(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
})
})
}
if (self.status === 'rejected') {
return promise2 = new Promise(function (resolve, reject) {
setTimeout(function (reason) {
try {
var x = onRejected(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
})
})
}
if (self.status === 'pending') {
return promise2 = new Promise(function (resolve, reject) {
self.onResolvedCallback.push(function (value) {
try {
var x = onResolved(value);
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error);
}
});
self.onRejectedCallback.push(function (reason) {
try {
var x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject)
} catch (error) {
reject(error);
}
});
})
}
}
Promise.prototype.catch = function (onRejected) {
return this.then(null, onRejected)
}
Promise.deferred = Promise.defer = function () {
var dfd = {}
dfd.promise = new Promise(function (resolve, reject) {
dfd.resolve = resolve
dfd.reject = reject
})
return dfd
}